Skip to content

Commit

Permalink
[Tezos]: Blind signing support (#2956)
Browse files Browse the repository at this point in the history
* feat(tezos): blind signing support
* refactoring encoded op name and type
* Add manual step
Co-authored-by: hewigovens <[email protected]>
  • Loading branch information
Milerius authored Feb 24, 2023
1 parent 4c40f20 commit 714bfac
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
16 changes: 10 additions & 6 deletions src/Tezos/Signer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ using namespace TW;
namespace TW::Tezos {

Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept {
auto operationList = Tezos::OperationList(input.operation_list().branch());
for (Proto::Operation operation : input.operation_list().operations()) {
operationList.addOperation(operation);
}

auto signer = Signer();
PrivateKey key = PrivateKey(Data(input.private_key().begin(), input.private_key().end()));
Data encoded = signer.signOperationList(key, operationList);
Data encoded;
if (input.encoded_operations().empty()) {
auto operationList = Tezos::OperationList(input.operation_list().branch());
for (Proto::Operation operation : input.operation_list().operations()) {
operationList.addOperation(operation);
}
encoded = signer.signOperationList(key, operationList);
} else {
encoded = signer.signData(key, TW::data(input.encoded_operations()));
}

auto output = Proto::SigningOutput();
output.set_encoded(encoded.data(), encoded.size());
Expand Down
5 changes: 4 additions & 1 deletion src/proto/Tezos.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ message SigningInput {
// One or more operations
OperationList operation_list = 1;

// Encoded operation bytes obtained with $RPC_URL/chains/main/blocks/head/helpers/forge/operations, operation_list will be ignored.
bytes encoded_operations = 2;

// The secret private key used for signing (32 bytes).
bytes private_key = 2;
bytes private_key = 3;
}

// Result containing the signed and encoded transaction.
Expand Down
30 changes: 30 additions & 0 deletions swift/Tests/Blockchains/TezosTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,34 @@ class TezosTests: XCTestCase {

XCTAssertEqual(output.encoded.hexString, expected)
}

public func testSignEncodedBytes() throws {

let key = Data(hexString: "3caf5afaed067890cd850efd1555df351aa482badb4a541c29261f1acf261bf5")!
let bytes = Data(hexString: "64aa7792af40de41371a72b3342daa7bf3d2b5a84511e9074341fdd52148dd9d6c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542850f96c3a1079d780080ade2040155959998da7e79231e2be8ed8ff373ac1b1574b000ffff04737761700000009e070703060707020000000807070508030b000007070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a4438457907070080dac409070700bdf892a1a291e196aa0503066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0497c3a107f10f180001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f76650000002d070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900006c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0498c3a107f70f090001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f766500000036070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900bdf892a1a291e196aa056c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542e71599c3a107fabb01400001b1f0d7affc39861f7f5c75f917f683d2e9f55e3100ffff04737761700000009a070700000707000007070001070700bdf892a1a291e196aa05070700a3f683c2a6d80a07070100000018323032332d30322d32345431333a34303a32322e3332385a070705090100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484805090100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a443845796c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049ac3a107f50f1b000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050507070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a52717572617400006c00ad756cb46ba6f59efa8bd10ff544ba9d20d0954285109bc3a107a0820100000155959998da7e79231e2be8ed8ff373ac1b1574b000ffff0473776170000000a1070703060707020000000807070508030b000807070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a44384579070700a3f683c2a6d80a070700a4f096bfbe9df6f0e00603066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049cc3a107ed0f00000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050807070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a5271757261740000")!
let input = TezosSigningInput.with {
$0.privateKey = key
$0.encodedOperations = bytes
}

let output: TezosSigningOutput = AnySigner.sign(input: input, coin: .tezos)

let expected = "64aa7792af40de41371a72b3342daa7bf3d2b5a84511e9074341fdd52148dd9d6c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542850f96c3a1079d780080ade2040155959998da7e79231e2be8ed8ff373ac1b1574b000ffff04737761700000009e070703060707020000000807070508030b000007070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a4438457907070080dac409070700bdf892a1a291e196aa0503066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0497c3a107f10f180001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f76650000002d070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900006c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0498c3a107f70f090001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f766500000036070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900bdf892a1a291e196aa056c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542e71599c3a107fabb01400001b1f0d7affc39861f7f5c75f917f683d2e9f55e3100ffff04737761700000009a070700000707000007070001070700bdf892a1a291e196aa05070700a3f683c2a6d80a07070100000018323032332d30322d32345431333a34303a32322e3332385a070705090100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484805090100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a443845796c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049ac3a107f50f1b000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050507070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a52717572617400006c00ad756cb46ba6f59efa8bd10ff544ba9d20d0954285109bc3a107a0820100000155959998da7e79231e2be8ed8ff373ac1b1574b000ffff0473776170000000a1070703060707020000000807070508030b000807070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a44384579070700a3f683c2a6d80a070700a4f096bfbe9df6f0e00603066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049cc3a107ed0f00000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050807070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a5271757261740000e10077fc3068aaaf1c7779e1dc2c396b3b40d73ddda04648bf4b16ac2e747c89b461771488e80da3aa30fc18c90de99fd358bfb76683f3c3ec250b1ee09b6d07"

XCTAssertEqual(output.encoded.hexString, expected)

// How to do it without AnySigner
var watermark = Data([0x03])
watermark.append(bytes)

let hash = Hash.blake2b(data: watermark, size: 32)
let privateKey = PrivateKey(data: key)!
let signature = privateKey.sign(digest: hash, curve: .ed25519)!

var signed = Data()
signed.append(bytes)
signed.append(signature)

XCTAssertEqual(signed.hexString, expected)
}
}
15 changes: 15 additions & 0 deletions tests/chains/Tezos/TWAnySignerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ TEST(TWAnySignerTezos, SignFA2) {
ASSERT_EQ(hex(output.encoded()), "1b1f9345dc9f77bd24b09034d1d2f9a28f02ac837f49db54b8d68341f53dc4b76c00fe2ce0cccc0214af521ad60c140c5589b4039247a08d0695d8b601a08d0600000136767f88850bae28bfb9f46b73c5e87ede4de12700ffff087472616e7366657200000066020000006107070100000024747a31696f7a36326b447736476d35484170655174633150476d4e32775042744a4b5550020000003107070100000024747a31696f7a36326b447736476d35484170655174633150476d4e32775042744a4b555007070000000a552d24710d6c59383286700c6c2917b25a6c1fa8b587e593c289dd47704278796792f1e522c1623845ec991e292b0935445e6994850bd03f035a006c5ed93806");
}

TEST(TWAnySignerTezos, BlindSign) {
// Successfully broadcasted: https://ghostnet.tzkt.io/oobGgTkDNz9eqGVXiU4wShPZydkroCrmbKjoDcfSqhnM7GmcdEu/15229334
auto key = parse_hex("3caf5afaed067890cd850efd1555df351aa482badb4a541c29261f1acf261bf5");
auto bytes = parse_hex("64aa7792af40de41371a72b3342daa7bf3d2b5a84511e9074341fdd52148dd9d6c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542850f96c3a1079d780080ade2040155959998da7e79231e2be8ed8ff373ac1b1574b000ffff04737761700000009e070703060707020000000807070508030b000007070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a4438457907070080dac409070700bdf892a1a291e196aa0503066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0497c3a107f10f180001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f76650000002d070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900006c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0498c3a107f70f090001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f766500000036070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900bdf892a1a291e196aa056c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542e71599c3a107fabb01400001b1f0d7affc39861f7f5c75f917f683d2e9f55e3100ffff04737761700000009a070700000707000007070001070700bdf892a1a291e196aa05070700a3f683c2a6d80a07070100000018323032332d30322d32345431333a34303a32322e3332385a070705090100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484805090100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a443845796c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049ac3a107f50f1b000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050507070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a52717572617400006c00ad756cb46ba6f59efa8bd10ff544ba9d20d0954285109bc3a107a0820100000155959998da7e79231e2be8ed8ff373ac1b1574b000ffff0473776170000000a1070703060707020000000807070508030b000807070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a44384579070700a3f683c2a6d80a070700a4f096bfbe9df6f0e00603066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049cc3a107ed0f00000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050807070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a5271757261740000");

Proto::SigningInput input;
input.set_private_key(key.data(), key.size());
input.set_encoded_operations(bytes.data(), bytes.size());

Proto::SigningOutput output;
ANY_SIGN(input, TWCoinTypeTezos);

EXPECT_EQ(hex(output.encoded()), "64aa7792af40de41371a72b3342daa7bf3d2b5a84511e9074341fdd52148dd9d6c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542850f96c3a1079d780080ade2040155959998da7e79231e2be8ed8ff373ac1b1574b000ffff04737761700000009e070703060707020000000807070508030b000007070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a4438457907070080dac409070700bdf892a1a291e196aa0503066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0497c3a107f10f180001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f76650000002d070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900006c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd0498c3a107f70f090001543aa1803f0bbe2099809ab067dfa8a4cbc1c26a00ffff07617070726f766500000036070701000000244b5431516f64676b5974754e79664a726a72673854515a586d64544643616d373268533900bdf892a1a291e196aa056c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542e71599c3a107fabb01400001b1f0d7affc39861f7f5c75f917f683d2e9f55e3100ffff04737761700000009a070700000707000007070001070700bdf892a1a291e196aa05070700a3f683c2a6d80a07070100000018323032332d30322d32345431333a34303a32322e3332385a070705090100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484805090100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a443845796c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049ac3a107f50f1b000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050507070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a52717572617400006c00ad756cb46ba6f59efa8bd10ff544ba9d20d0954285109bc3a107a0820100000155959998da7e79231e2be8ed8ff373ac1b1574b000ffff0473776170000000a1070703060707020000000807070508030b000807070100000018323032332d30322d32345431333a34303a32322e3332385a07070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a7376617868484807070100000024747a315377326d4641557a626b6d37646b47434472626542734a54547456374a44384579070700a3f683c2a6d80a070700a4f096bfbe9df6f0e00603066c00ad756cb46ba6f59efa8bd10ff544ba9d20d09542cd049cc3a107ed0f00000193d22b59c496c94504729be1c671ec1d1d7a9cf000ffff107570646174655f6f70657261746f72730000005f020000005a050807070100000024747a31625443473754415535523736356f4458694c4d63385a4537546a73766178684848070701000000244b543147504a44546638475a73704363616e6147324b684d764775334e4a5271757261740000e10077fc3068aaaf1c7779e1dc2c396b3b40d73ddda04648bf4b16ac2e747c89b461771488e80da3aa30fc18c90de99fd358bfb76683f3c3ec250b1ee09b6d07");
}

TEST(TWAnySignerTezos, Sign) {
auto key = parse_hex("2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6f");
auto revealKey = parse_hex("311f002e899cdd9a52d96cb8be18ea2bbab867c505da2b44ce10906f511cff95");
Expand Down

0 comments on commit 714bfac

Please sign in to comment.