Skip to content

多重签名

Hantao Sun edited this page Jan 15, 2020 · 7 revisions

介绍

多重签名用于从多签模板地址发起交易时,这笔交易成为多签交易。

如何创建多签模版,请参阅create multisigCreate weighted-multisig

组成

在多签交易中,vchSig包含两个部分:其一是多签模版的内容,另一个是多重签名。

           template    signature
vchSig: |____________|___________|

模版

模版内容是二进制串,他的长度取决于模版中定义的key的数量。key最多255个

            required   keys-length  1st-public-key  1st-key-weight      nth-public-key  nth-key-weight
template: |__________|____________|_______________|_______________|...|_______________|_______________|
             1 byte      8 bytes       32 bytes        1 byte               32 bytes        1 byte
  • required是参与多签的最小权重之和。
  • keys-length是key的数量。
  • nth-public-key是第n个参与的公钥。
  • nth-key-weight是第n个公钥的权重。

由于公钥是32字节的,可以把它看成是一个uint256。公钥的顺序由小端的uint256大小来决定的

可能的实现:

    // uint256 is uint[8]
    bool operator<(const uint256& a, const uint256& b)
    {
        for (int i = 31; i >= 0; i--)
        {
            if (a[i] < b[i])
                return true;
            else if (a[i] > b[i])
                return false;
        }
        return false;
    }

签名

签名包含三部分:

                          index                     R1           S1              Rn            Sn
signature: |_________________________________|____________|____________|...|____________|____________|
             (keys-length - 1) / 8 + 1 bytes    32 bytes     32 bytes         32 bytes      32 bytes
  • index是一个bitmap(位图),用于表明有哪些key参与了多重签名,其位置和key的顺序有关。如果将index看成是一个uint8数组idx[],那么设置序号为n的公钥方法:idx[n / 8] & (1 << (n % 8))
  • (Ri,Si)libsodiumcrypto_sign_ed25519_detached()算法一样
  • S = Si + ... + Sj
    • SHA512的所有参数都按二进制计算
    • Ri = ri * B, B是ed25519的基点。
    • Si = ri + SHA512(Ri,Pi,M) * si是ed25519的标量加法scalar + scalar (mod L)和乘法scalar * scalar (mod L)
    • ri = SHA512(SHA512(ki)[32, 64),M)
    • ki是私钥
    • Pi是公钥
    • si = Clamp(SHA512(ki)[0, 32)), ki是私钥. 有等式 Pi = si * B
      void Clamp(unsigned char k[32])
      {
          k[0] &= 248;
          k[31] &= 127;
          k[31] |= 64;
      }
      
    • M是待签名内容,在多签交易中,它是Hash(IOStream(version,type,timestamp,lockuntil,anchor,input,sendto,amount,txfee,data)), 参阅IOStream:
        version: uint16
        type: uint16
        timestamp: uint32
        lockuntil: uint32
        anchor: uint256
        input: vector<out> (out: uint256 + uint8)
        sendto: uint8 + uint256
        amount: int64
        txfee: int64
        data: vector<uint8>

验证

  • `Si * B = (ri + SHA512(Ri,Pi,M) * si) * B = Ri + SHA512(Ri,Pi,M) * Pi

例子(测试网络)

  • 创建一个3-2的多签模版
    • key在rpc中显示为数字,在内存中用小端表示
    • key1:
      • privkey(数字): 78670388774d3ff0d3ce1496bd510a2159e91ad32bdc6cc5c44001ebe1852ad7
      • pubkey(数字): b0b4d36a03f44b98a5d78260a29be8cb014b6c84d9444a9a7084b7752ad8b1ce
      • privkey(小端): d72a85e1eb0140c4c56cdc2bd31ae959210a51bd9614ced3f03f4d7788036778
      • pubkey(小端): ceb1d82a75b784709a4a44d9846c4b01cbe89ba26082d7a5984bf4036ad3b4b0
    • key2:
      • privkey(数字): b7edd08c0e68d0a5756cd9a1c2d7cd1e948b260bf43aeead62a7a4d3eef34f78
      • pubkey(数字): 518b0312ae41b5e5134c82f9b45bd8649c6e7474965fb868a7b20cfd24bf77af
      • privkey(小端): 784ff3eed3a4a762adee3af40b268b941ecdd7c2a1d96c75a5d0680e8cd0edb7
      • pubkey(小端): af77bf24fd0cb2a768b85f9674746e9c64d85bb4f9824c13e5b541ae12038b51
    • key3:
      • privkey(数字): 551896b88c1d692b072bca70953dfe549b21d2237c9407eadeb67598a272a708
      • pubkey(数字): 01e7adfbc8f5a39248b9bd33cdf131910f832d222b621912d37fc22dadaaf4aa
      • privkey(小端): 08a772a29875b6deea07947c23d2219b54fe3d9570ca2b072b691d8cb8961855
      • pubkey(小端): aaf4aaad2dc27fd31219622b222d830f9131f1cd33bdb94892a3f5c8fbade701
    • 简单多签模板, 使用rpc命令创建: addnewtemplate multisig '{"required": 2, "pubkeys": ["b0b4d36a03f44b98a5d78260a29be8cb014b6c84d9444a9a7084b7752ad8b1ce", "518b0312ae41b5e5134c82f9b45bd8649c6e7474965fb868a7b20cfd24bf77af", "01e7adfbc8f5a39248b9bd33cdf131910f832d222b621912d37fc22dadaaf4aa"]}'
    • 多签模板的地址: 208097hf8yx96yfhpe9jjgmq4xnyzkacbw3zanqtq4rm2zp26wknq3qv4
    • 多签模板的内容(hex): 020300000000000000aaf4aaad2dc27fd31219622b222d830f9131f1cd33bdb94892a3f5c8fbade70101af77bf24fd0cb2a768b85f9674746e9c64d85bb4f9824c13e5b541ae12038b5101ceb1d82a75b784709a4a44d9846c4b01cbe89ba26082d7a5984bf4036ad3b4b001
    • 多签模板的结构信息:
    {
        "type" : "template",
        "address" : "208097hf8yx96yfhpe9jjgmq4xnyzkacbw3zanqtq4rm2zp26wknq3qv4",
        "template" : "multisig",
        "templatedata" : {
            "type" : "multisig",
            "hex" : "0200020300000000000000aaf4aaad2dc27fd31219622b222d830f9131f1cd33bdb94892a3f5c8fbade70101af77bf24fd0cb2a768b85f9674746e9c64d85bb4f9824c13e5b541ae12038b5101ceb1d82a75b784709a4a44d9846c4b01cbe89ba26082d7a5984bf4036ad3b4b001",
            "multisig" : {
                "required" : 2,
                "addresses" : [
                    "1nbtanb9dr9zx64gsc8nj4bc31y8k3wed6eyvjj4jmftwhyxdww0q8wfe",
                    "1nxvvy97x1jsaet5rbyb78x3ekhjdgpxmz614r4z5pn0tw4g3hd8vp18g",
                    "1strxgaknpy2716ja8kcr8v2b075yh6x2c21df9cr9ft06tpkpjr3g7g4"
                ]
            }
        }
    }
  • 从多签模板创建一笔交易
    • 用rpc命令创建交易: createtransaction 208097hf8yx96yfhpe9jjgmq4xnyzkacbw3zanqtq4rm2zp26wknq3qv4 1965p604xzdrffvg90ax9bk0q3xyqn5zz2vc9zpbe3wdswzazj7d144mm 1
    • 返回了交易信息(hex): 010000005f2e1d5e00000000d4a8f445791e35471b69254e444a4eac2e2448f57b420a6535f935c30000000001502a5eda0bce416485444b91bda0271b1dfe04a772f807c749ac3ce022fb165e0001498b63009dfb70f7ee0902ba95cc171f7d7a97ff16d89fd96e1f1b9e7d5f91da40420f000000000064000000000000000000
    • tx的结构信息:
    {
        "txid" : "5e1d2e5f2bc4a57080f5aaa8dd9451b807eb650cd5d72e5604f181ab94b23a09", (小端数字hex)
        "version" : 1,
        "type" : "token",
        "time" : 1578970719,
        "lockuntil" : 0,
        "anchor" : "00000000c335f935650a427bf548242eac4e4a444e25691b47351e7945f4a8d4", (小端数字hex)
        "vin" : [
            {
                "txid" : "5e16fb22e03cac49c707f872a704fe1d1b27a0bd914b44856441ce0bda5e2a50", (小端数字hex)
                "vout" : 0
            }
        ],
        "sendfrom" : "208097hf8yx96yfhpe9jjgmq4xnyzkacbw3zanqtq4rm2zp26wknq3qv4",
        "sendto" : "1965p604xzdrffvg90ax9bk0q3xyqn5zz2vc9zpbe3wdswzazj7d144mm",
        "amount" : 1.000000,
        "txfee" : 0.000100,
        "data" : "",
        "sig" : "",
        "fork" : "00000000c335f935650a427bf548242eac4e4a444e25691b47351e7945f4a8d4",
        "confirmations" : 0
    }
  • 多签时的公共数据计算:
    • key按数字大小排序(数字):
      • 01e7adfbc8f5a39248b9bd33cdf131910f832d222b621912d37fc22dadaaf4aa
      • 518b0312ae41b5e5134c82f9b45bd8649c6e7474965fb868a7b20cfd24bf77af
      • b0b4d36a03f44b98a5d78260a29be8cb014b6c84d9444a9a7084b7752ad8b1ce
    • M: 是tx待签名hash
      • IOStream(version,type,timestamp,lockuntil,anchor,input,sendto,amount,txfee,data): 010000005f2e1d5e00000000d4a8f445791e35471b69254e444a4eac2e2448f57b420a6535f935c30000000001502a5eda0bce416485444b91bda0271b1dfe04a772f807c749ac3ce022fb165e0001498b63009dfb70f7ee0902ba95cc171f7d7a97ff16d89fd96e1f1b9e7d5f91da40420f0000000000640000000000000000
      • Blake2b(IOStream(version,type,timestamp,lockuntil,anchor,input,sendto,amount,txfee,data)): a42605681ee4d3ea007cdea07109b7eb9cd16d7494e4c47a8ac6b5c89e25a90c
  • key 518b0312ae41b5e5134c82f9b45bd8649c6e7474965fb868a7b20cfd24bf77af的签名:
    • r2 = SHA512(SHA512(k2)[32, 64),M) mod L
      • k2(little-endian): 784ff3eed3a4a762adee3af40b268b941ecdd7c2a1d96c75a5d0680e8cd0edb7
      • SHA512(k2): de9c6efbc2739817d3ce6fd039c844662c5c9df2812de0ff259f4f27dcdd6d6492aee889288cedb9ed662fc8f72010a345b53897835a805e0a5ee6bc018104d8, PS: k2 is binary in SHA512
      • M: a42605681ee4d3ea007cdea07109b7eb9cd16d7494e4c47a8ac6b5c89e25a90c
      • (SHA512(k2)[32, 64),M): 92aee889288cedb9ed662fc8f72010a345b53897835a805e0a5ee6bc018104d8a42605681ee4d3ea007cdea07109b7eb9cd16d7494e4c47a8ac6b5c89e25a90c
      • SHA512(SHA512(k2)[32, 64),M): 1aa406f67053125bc13fcb50d9f343eece23d9bd86fa0fc855c45a013b2b53e9e092b02788dd8077876933c0fe0f9d2bdcce35ac24265cad72bedecdfca3b265
      • SHA512(SHA512(k2)[32, 64),M) (number): 65b2a3fccddebe72ad5c2624ac35cedc2b9d0ffec03369877780dd8827b092e0e9532b3b015ac455c80ffa86bdd923ceee43f3d950cb3fc15b125370f606a41a
      • SHA512(SHA512(k2)[32, 64),M) mod L (number): af12ac1fd0b1507df680dd83db53bc6a8e612b2aa657d810f1cb0c7e1f8ca002
    • R2 = r2 * B: f34c890f3f7534e8bbfae098729d00d5fb933e6dc53c6d81b86a5cfea0e676b2
    • SHA512(R2,P2,M) mod L:
      • P2(little-endian): af77bf24fd0cb2a768b85f9674746e9c64d85bb4f9824c13e5b541ae12038b51
      • (R2,P2,M): f34c890f3f7534e8bbfae098729d00d5fb933e6dc53c6d81b86a5cfea0e676b2af77bf24fd0cb2a768b85f9674746e9c64d85bb4f9824c13e5b541ae12038b51a42605681ee4d3ea007cdea07109b7eb9cd16d7494e4c47a8ac6b5c89e25a90c
      • SHA512(R2,P2,M): d65f3933bacc7c43568edc245250189d89d260905c47a91ee708025cd4a901717d4202eee984790bc7365013e617de03f5e9b18ce1dbe723a03c9950c13e4820
      • SHA512(R2,P2,M) (number): 20483ec150993ca023e7dbe18cb1e9f503de17e6135036c70b7984e9ee02427d7101a9d45c0208e71ea9475c9060d2899d18505224dc8e56437cccba33395fd6
      • SHA512(R2,P2,M) mod L (number): 0388b6cf5bc4fde535736d93e43dedd239b9afae4ae2e82708db01ba6171013d
    • S2 = r2 + SHA512(R2,P2,M) * s2
      • s2 = Clamp(SHA512(k2)[0, 32))
        • SHA512(k2)[0, 32): de9c6efbc2739817d3ce6fd039c844662c5c9df2812de0ff259f4f27dcdd6d64
        • Clamp(SHA512(k2)[0, 32)): d89c6efbc2739817d3ce6fd039c844662c5c9df2812de0ff259f4f27dcdd6d64
      • s2 (number): 646ddddc274f9f25ffe02d81f29d5c2c6644c839d06fced3179873c2fb6e9cd8
      • SHA512(R2,P2,M) * s2 mod L (number): 0db582a090281cc5207610273cef0640d8232ece74cc0acaa0af93505e93338c
      • (r2 + SHA512(R2,P2,M) * s2) mod L (number): 00560ec00e34e8b6314e67cd671a67cf2e0088cb55b1eeeac5ede2062149724e
      • S2 (little-endian): 4e72492106e2edc5eaeeb155cb88002ecf671a67cd674e31b6e8340ec00e5600
    • sign = template + multisig
      • multisig = index + R2 + S2
        • index: 02
        • multisig: 02f34c890f3f7534e8bbfae098729d00d5fb933e6dc53c6d81b86a5cfea0e676b24e72492106e2edc5eaeeb155cb88002ecf671a67cd674e31b6e8340ec00e5600
      • sign = 020300000000000000aaf4aaad2dc27fd31219622b222d830f9131f1cd33bdb94892a3f5c8fbade70101af77bf24fd0cb2a768b85f9674746e9c64d85bb4f9824c13e5b541ae12038b5101ceb1d82a75b784709a4a44d9846c4b01cbe89ba26082d7a5984bf4036ad3b4b00102f34c890f3f7534e8bbfae098729d00d5fb933e6dc53c6d81b86a5cfea0e676b24e72492106e2edc5eaeeb155cb88002ecf671a67cd674e31b6e8340ec00e5600
  • key 01e7adfbc8f5a39248b9bd33cdf131910f832d222b621912d37fc22dadaaf4aa的签名:
    • r1 = SHA512(SHA512(k1)[32, 64),M) mod L
      • k1(little-endian): 08a772a29875b6deea07947c23d2219b54fe3d9570ca2b072b691d8cb8961855
      • SHA512(k1): 231b4f6af41033f66c68ff30ae7f660f9a2cd0918ed2b7ab2bbece504477ecdb8a030b2e437e580f61a9a121b62fff6d7eeef0e31d43821d65daf6723bdc0408, PS: k1 is binary in SHA512
      • M: a42605681ee4d3ea007cdea07109b7eb9cd16d7494e4c47a8ac6b5c89e25a90c
      • (SHA512(k1)[32, 64),M): 8a030b2e437e580f61a9a121b62fff6d7eeef0e31d43821d65daf6723bdc0408a42605681ee4d3ea007cdea07109b7eb9cd16d7494e4c47a8ac6b5c89e25a90c
      • SHA512(SHA512(k1)[32, 64),M): 75fe69613613857458b4c6fad67cf913b7acc13359662b084d4b9bcc7fbbecd6e5ab8c2ac91dc1f890689fc8b61dfb2fc157021d059dcc0042e708971f1563ff
      • SHA512(SHA512(k1)[32, 64),M) (number): ff63151f9708e74200cc9d051d0257c12ffb1db6c89f6890f8c11dc92a8cabe5d6ecbb7fcc9b4b4d082b665933c1acb713f97cd6fac6b458748513366169fe75
      • SHA512(SHA512(k1)[32, 64),M) mod L (number): 001ddf543af81baa3fda6f359238670ac86cc8974e5fa1a175707aed95513936
    • R1 = r1 * B: 4d5d54d4ea19c17ff4a0a8537de6b429b98ea847410dac229b69ff50b0effa27
    • SHA512(R1,P1,M) mod L:
      • P1(little-endian): aaf4aaad2dc27fd31219622b222d830f9131f1cd33bdb94892a3f5c8fbade701
      • (R1,P1,M): 4d5d54d4ea19c17ff4a0a8537de6b429b98ea847410dac229b69ff50b0effa27aaf4aaad2dc27fd31219622b222d830f9131f1cd33bdb94892a3f5c8fbade701a42605681ee4d3ea007cdea07109b7eb9cd16d7494e4c47a8ac6b5c89e25a90c
      • SHA512(R1,P1,M): 6d2aa76a3e82058a137929e4e38698c121631f33f3316c3c99b0486a9833bcd54fba546a20123867846807c54e0c8360f865b74e69cc83ad15feafa4d1abfea4
      • SHA512(R1,P1,M) (number): a4feabd1a4affe15ad83cc694eb765f860830c4ec5076884673812206a54ba4fd5bc33986a48b0993c6c31f3331f6321c19886e3e42979138a05823e6aa72a6d
      • SHA512(R1,P1,M) mod L (number): 01652bccb892f34e98591976f7f7dae7445e47b97e62c09a5a2f5869de78f903
    • S1 = r1 + SHA512(R1,P1,M) * s1
      • s1 = Clamp(SHA512(k1)[0, 32))
        • SHA512(k1)[0, 32): 231b4f6af41033f66c68ff30ae7f660f9a2cd0918ed2b7ab2bbece504477ecdb
        • Clamp(SHA512(k2)[0, 32)): 201b4f6af41033f66c68ff30ae7f660f9a2cd0918ed2b7ab2bbece504477ec5b
      • s1 (number): 5bec774450cebe2babb7d28e91d02c9a0f667fae30ff686cf63310f46a4f1b20
      • SHA512(R1,P1,M) * s1 mod L (number): 0350177f8681357511828445720de12b5f40edc080e56227bc3a158bad522c55
      • (r1 + SHA512(R1,P1,M) * s1) mod L (number): 036df6d3c179511f515cf37b0446483627adb657cf4503c931aa907942a3658b
      • S1 (little-endian): 8b65a3427990aa31c90345cf57b6ad27364846047bf35c511f5179c1d3f66d03
    • sign = template + multisig
      • multisig = index + R1 + S1 + R2 + S2
        • index: 03 = 02 + 01
        • multisig: 4d5d54d4ea19c17ff4a0a8537de6b429b98ea847410dac229b69ff50b0effa278b65a3427990aa31c90345cf57b6ad27364846047bf35c511f5179c1d3f66d03f34c890f3f7534e8bbfae098729d00d5fb933e6dc53c6d81b86a5cfea0e676b24e72492106e2edc5eaeeb155cb88002ecf671a67cd674e31b6e8340ec00e5600
      • sign = 020300000000000000aaf4aaad2dc27fd31219622b222d830f9131f1cd33bdb94892a3f5c8fbade70101af77bf24fd0cb2a768b85f9674746e9c64d85bb4f9824c13e5b541ae12038b5101ceb1d82a75b784709a4a44d9846c4b01cbe89ba26082d7a5984bf4036ad3b4b001034d5d54d4ea19c17ff4a0a8537de6b429b98ea847410dac229b69ff50b0effa278b65a3427990aa31c90345cf57b6ad27364846047bf35c511f5179c1d3f66d03f34c890f3f7534e8bbfae098729d00d5fb933e6dc53c6d81b86a5cfea0e676b24e72492106e2edc5eaeeb155cb88002ecf671a67cd674e31b6e8340ec00e5600
Clone this wiki locally