Google Tink 是一個用於整合密碼學方法的開源儲存庫。它使用最佳實踐來降低風險,並簡化程式碼整合。目前它支援 Golang Java、C++、Python 和 Objective-C。由於 Java 在 Android 裝置上得到良好的支援,因此該程式碼已整合到廣泛的應用程式中,包括 Google Pay。
我們在密碼學中使用的一種標準方法是使用私鑰簽署訊息,並使用公鑰證明簽署。因此,如果 Bob 有一個金鑰對,他會使用他的私鑰來簽署訊息,然後 Alice 將使用 Bob 的公鑰來證明是 Bob 簽署的。它還將證明該訊息沒有被 Eve 更改。
我們在許多應用程式中使用此方法。一個例子是在 Bitcoin 轉帳中,Bob 簽署一筆交易以支付 Alice 給定數量的 bitcoins。他使用他的私鑰(位於他的錢包中)簽署此交易,然後將其與他的公鑰一起添加到區塊鏈上。任何想要檢查轉帳的人都會使用 Bob 的公鑰檢查簽名。
現在讓我們看看 Google Tink 如何產生數位簽名程式碼。雖然我們可以將 ECDSA、EdDSA 和 RSA 與 Google Tink 一起使用,但一種後量子穩健方法使用 ML-DSA。具體來說,它使用 ML-DSA-65,它具有 192-bit 安全級別。然後,我們可以使用金鑰對的私鑰,使用 sign() 方法簽署訊息:
params, _:= mldsa.NewParameters(mldsa.MLDSA65, mldsa.VariantNoPrefix)
manager := keyset.NewManager()
keyID,_ := manager.AddNewKeyFromParameters(params)
manager.SetPrimary(keyID)
privKey, _ := manager.Handle()
我們可以使用私鑰產生一個新的簽署者:
signer, _ := signature.NewSigner(privKey)
signatureBytes, _ := signer.Sign(message)
然後產生公鑰,並驗證簽名:
pubKey, _ := privKey.Public()
verifier, _:= signature.NewVerifier(pubKey)
一個範例執行顯示了訊息「Testing 123」的簽名,以及截斷的簽名:
Message: Testing 123
Signature (truncated to 100 bytes): a56ea8ccb87de8db79e3cdfd06c6f99de36c67799d4ca4d04335306f08514852921b0b4e3654a0c62785ab5014f8c19f1b1916bcae53bc96a19b6e8197e640613faaa296457ae1daebbe572e7c894c71e5e9a2697ce99a1fe84dbd48f9ee6c85b60c0f9594abe75242b51a44c7a50401a01585f8253a8e0a4a0d6879861caa6ea3b215806b4287afded72407467612ab44fb3dce1d2ddb0ffec28485451b98ba0e2e57f7765ca39d4054af7096cb6b5618c6792bf3e93d76425aa24cd62732936b05cb11381f551d
Signature size: 3309 bytes
Private Key: primary_key_id:451338756 key_info:{type_url:"type.googleapis.com/google.crypto.tink.MlDsaPrivateKey" status:ENABLED key_id:451338756 output_prefix_type:RAW}
Public Key: primary_key_id:451338756 key_info:{type_url:"type.googleapis.com/google.crypto.tink.MlDsaPublicKey" status:ENABLED key_id:451338756 output_prefix_type:RAW}
我們可以看到 ML-DSA 的簽名大小為 3,309 bytes。就金鑰對而言,我們的私鑰採用 RAW 格式:
Private Key (first 150 characters) [key_data:{
type_url:"type.googleapis.com/google.crypto.tink.MlDsaPrivateKey"
value:"\x12 \x8f\xb8dwHT\"\xf64\x0e\xbd\x17\xa9p9}~\xde\xc6??B\x87~\x99\xb2\x91C\xa7:b\x8d\x1a\xa7\x0f\x12\xa0\x0f\x9a\xd1D\xaf\x11%\x1e/%!\xdbNd\xf6/\x03\xbc\xbd\x870#.!\xabp\x9d\x8b~{\x8drE%\x1f\x00`i\xebzF\x16\x857m\xe4\x12;\x03ǝ\xe94Y\xde7\xbf\xefX^\x97\xcf15C\xa0L\x9f{\xbd\x92c\xd8-Q>\xbc\x9a<'\x97\xacA\x19\xe2\x92\x1avffL\xb7$`\xfe\x159S\xa4ȴB\xd7\xcej\xc0\xb1\x7f¸L\xe2p\x9a͖\x1d]\xc1Ԩ\xfa%\xe9\xc8md\xbc4~\xcd/`\xc3'\x0b\xa7\xba\x942tA\x93\xbc\xca\xf6\x87\x82s\xd6\xcf\x1c3'N\xe2S\x9b?\xacb\xb6\xfe\xdd6\xefm%\t\x12)\xc7\x14+OƖ:\xc8U顔\xa8\xady\xa5Ƅۯ\xee\x08:\x87\xa3M\x80\x07\xebђ\x88\x7f\xf2A\x07\x86}\x86\x94Z\xf9Ǡ4+\x1ag\"\x9f&\xb85\xbb\xe8\xce\x15\x97\xd6*\xb4\xa1\xe5\\1\xff\x95\xeeO]\xffݫg\x1d\xf9\xb7\x1a\xfdRf+\x90\x19\x96\xca\x14=\xbc\x95\xdc;\xef\x93\xc5Q\xae\x9c!\xcf'\x83)\xb3s\x81|o\xa7zo\x0b\xec\xc5\x14\xc6S:\x1b\x8c\xbe\xd2'\xc0\xd6d\x96pIF\x97\xa6l\x88\x0e\xa7\x1e\x02\r\x01L\x9c\xfb\rT\xef\xfffo\x8b^\xa6\xfcd+\x88\x7f\xe8E\x06\x93\xcc/Е\xb7\xf7\x17\x8c\xa5\xaf\x9f\x1bXZh\x985\x1cV\xfe\xce\xd4\x01\x98\x1f\xbe\x0fG\xc3%:\x8b\xfcg\x9c*pXn@Y\xd6\xd7\xd6\xe9X\x0e\xc3\x1d\xd5ݫ]\xeb\x1cW\xe7K\xbf5a3\xb2\x13\xd80}V1h\xa6o\x06`W\xc4?|\xfc\xd7\xe3\x9cc1t\xb2\xae\xf6N\xa0\x91pys+e\xe70\xf4\xe4hNy\xa6I\x95\xfb]\xd2p\x9c\x90^C%\x96օ\xadR۸\xbd%\xf4\xa2\xed\xe7\x7f\x93B(\xeaUjG\x19\r\xd0ɾ\x19\xe7\xc9\xd9}\xe4b\xf6\x12*\x05gy8\x15\xb5ι)\xaa\xe6\xe6\xc9ѕ\x17H$8b\xc6\xe3Ǘ\x9e\x94o\x9f)\x1c\xee]l\xb4\xc4P\xe0\xf9\x89\x15\xd0k\xdcH`\xb0\x92~y匳\xa3\xaf\x82-r\x0eY\x80\xc3;\xe0\x14\x04\xb4\x17v\xe2\xd1EV\x13%Q\x14\xee\xf2{1*or\x8c\x9c\xcf\x1cp|\x9b\x07\x85\x8d/\nF\xd3\x07Ҩ\x9af\xe290\x95\x80\x18\x10\x80V\x0b\x02w)\x8cU\x15\xa2\xa1\rn\x0e\x84\x04\x96\x97\x18\x1d\x00\xe0\xdf\xfe\xbcu\x9eI\xa5\x95a\x12ۍ\xd7Rr\xd4\xfa\xaa\x86\x18\x8a\xbdW\xdf\xfa\xb8N\x05\x92߶\x15¸\xa3t\xdbE/\x90\xeb\x81Ycx\xe9+\xb5\xf2\x05,ddz3k\x8b\xaf\x0bL\xd0ށ\xady\xc1yw\x80\x10\xd1ə\xedĤ\xc08\x0c\xb8\x1e\xc1\x0c/@\xf6\xf2\x1d\xd4\xfel詣\x98|r\xd8\x00[\x9c\x96\xf3\xabbx\x10\x16\x8c\xdcr*\x0b\xf9\x1f\xea\x84\xfcw|-\x86\xbf\t4\xea\xf0H\xbf\x95z.q\x02$\x8ei\x92J\xc1\x1b\x05\x94\nD\\\xb5\x1aD\x82\x1f\x17\xcfh\x8acA\xd6\x17\xe4\xa0\t矙\xddc$\xb6X@\xb9P\x16;^\x9a\xf1\xb3>\x18\xe7\x14\xb5rU\x86\x9d]q\xa6\xf5\xa4\xa4GkVw\xd7\xebv\x18\x13Q\xb2H8-\x83\x97\xbbM\xc5\xe8+@X/\xbe\xf0\xef\xec:\xe3\xa8N.a\x16\x0f\xb9\x00\xc9l^v\xac\x99\xebf9'%f\xe40\xe5\x934d\x9d-\x9eٙ\xff\xc2J\xbb+!ĻA\x16\xe9\x881\x9c\xab\x80\xfe\xd3\x10\xf1 \x8bn\xcf\xf0ょE5\x96U\xb5\x98(\x967\xfb\xa7\xa8B\xfb\xaaG\xaaz\x0c\x16_\xb8\x94\x93\x983\xfa\xe0W\x19\xc4gH\xef2\xe2FE\xfb\xc0\x8e@\"\x19\xb3\x87\"\xfe7p\xfb\xc9e\x9aoYh\xac-Uz\xeb\x8a\xf7\xaa|\xeb.\x91\x96w\tv\x98\xa4\xefN*\xa4\xfc\xd2s\xcbT\xa4\xbe\x16٤\x18$g\xc9m \ x19\xfd\x83\xf58\x94\xd1\xd1x\xbcȁM^\x9e\x1b\xf8\xacec\xf6$HQ\\w\xc1,\n\xf2Ό\xb0\xca\xc1(\xf0\xa12.\x9a\x82\xcc\xdb\xd0}}Hv`iU\x91\xcb^\x1e\\\xe2\xa4z\xe2gkˣ\\\xf7\xf3L+qc\x90멺t\xfd\xb9\x08\xce7\raA\x1f\xa3\xb5\xdf\x7fZ\x07O\xfa\xb1\x92\x9aaH\x15\x10r\x80!\xadt\xa9{\x0f܌JP\x7ft\x198\x95\xbc\x85\xa2D\xe3֊\r\x94\xdcg\x1a\x13\xff\xb72$\x97\xee\x9c;#Ɓij\x93\xce^+\x14\xb5Z\x05n\xdaR\xd1\xd9z\xea\xf9\t\xd0^\xf3k\x96$\xb7\x00A\xafLA\xc0\xf3\xbe\x05\xe6oE\x17\x07B<^\xe4)\xf3+l\xa2S\xa9\xe5UM\xa6)Wi\xf9=\x96\x84\xa9\x0f\x1f{Ij\x10\xac\xb5\xbc\x87қ~J\xebr\xa5/\xe0W\xd7\x0ee\xd5\x10g\x94\x96\xfcO\xb9\xcfΑqh\x94-)\xd5\x1a)\xb5K)5ysN\x82\xf8c\xc1>\xf9`r\xe2\xab\xec\xcf3fF\xa8\x11Lz\x84\x8a<;S\xdb*\x9b\x8f\xef\xe1-亾&\x0b\x14\xb0)k\xe9\xd4\xf3l-\xba\x13\x8cp\xde\xd9\x06\xf6\xd4\x1cf\r=\xc6/i\xc4\x02\x96g\xad\xdf\xc1\\$e\x02I\x1c\xbd\\',\xed\xa2wޯ\x15\x10\x85\x1a\x97~@\xe4\x1d\x8a|\x13}*\\\xfb[U\x12\\@\xd1\x19ecT\xf1\xfa\xbc\x89+\xfe\x18Te,\xd1\xd2h\xa0^\xef\xb7\xc0\x91\x82V]\x9bX,F\x14\x8f\xa6\xb0\xe9ͤT\x0f\xf3U\xf4.(>\x96\x01\xb3HRP\xac\x02\xba\x1e\x89\xe3\x0b$\xf4|\xf3\x98\x1c\xb6l\x07\x879\x9ezgk\x8f\x8b\x0e߀G\xd3\x15\xbeYV\x89\xfa\x13\x83j\xea\xbf\xe0z=\xda\x00`\x9b\xee=і|\x88\x98\x8e\x8a\x05LI\n$\x00\xa3or(\x99\xabs\xb9K0\x8f\xd7\x07\x8a\xb2\xfb\xb1B0\xcd\xc4\x12N\x0f\xc6h\x7fc\x0fEe\x03\xaey\x8b\xc1LE\x0eKd\xf5\x9d\xe3]\x18h\x91\x1d!\xfe\x8c\xb5\xc7\xc9\xf3\x1e\x1a%\xbd\xfc(\xe1\x11\x10ο;\xf5\xf8\xae\xb9d\xb9\xb8y`\x0f\xa7EtU\xba$\xa8\x19\x82N~\xad7\x17\xd7\x02`\x8d\x06\x97_ÿ\xa9\xf7\xf0\x9b\x9f\x0b\xb8\x11\xe4\xc6\xd0\x04\x90\x99\xac\x81\xcbC\x84\x15\xcd\xcch\xb36`u\x84\xbd\xc0R\x04\xd6\xee\xa47\xc3\x7f\xed\xfb3\xe36\xb4\x05\xdea]\x1b\x1cn=\xef0\x11\xaa\xdc(\xa7.\xe0F=b^s-\xfb\x1d&\xfb\x15\x07\x869\xab\x96U#\xaa\t\xf7\x14\x1eCؔ\xcfw\xfb\xa7S\x9dT\x17\xb7\x99Y&\x9a+\xae\x9a}A\r4z\xfd\x9d6\t\re\x16\xe3\xa5\r)\xe1\xe9\xf3\xf8\xa0\xce\x1b\x16\xd3cD-7\x1bK\xf6\x9d\xd7\t[\xfcQv\x08\xe8q\x8f\x1b\xefa\x12\x14'\x18P\x81:\x7f\xa2;\xb6\xc8\x13\xc5\xeb\xbd\xd2\xd9as\xa5(g\x9d\xd4\x02G\xbd\x0f5\xbd\xf3\xafj\x94\x0cװ\x81\x9aX\xbb\x88(\x1f\xa9\xc1ˋ%k\xa0y@\x95Y\x02d\xe9z4Tg\xce_ܦu\xd7\n)ܲf\x98\x80\x8f6%\xd0\x1c\xd6\x17\x0b\xb1\rN\xc2M@iw\xc8\x03\xf5\xdaYR\x7f\x84\xd1\x0eĎ\xd1\xc6ϯ\xeb\xa2\x03A\xb5\xeez\xa3\xce\xca\x00\xe9|\x94\rڀ\xe5ϟA\x99^\xcaNo\xf3)\xf0}\xfd\xd6:\x80\x83\xb4&\xaeWxZ\xa2G\x01\x19\xab\x14z\x9aR \xa9i\x0f\xcd\xc4Z\t\x83\xa1r\xb6eٰ\x07l\x06\xab\xe2\x88\xe5Z^ I\xeeǀ\xe4K\xb9*{+\xfb,\x9b\x84\x95u\xb5\x07\x02\xa0\x0cL\xd9\x0c\xedC\xe78s#\xa65\x05F4\x07\x93\xfc\xbdМ\xcc\xf0xQ@E\xe9\x1a\x02\x08\x01"
key_material_type:ASYMMETRIC_PRIVATE}
status:ENABLED key_id:113708819
output_prefix_type:RAW]:
和一個公鑰:
[key_data:{type_url:"type.googleapis.com/google.crypto.tink.MlDsaPublicKey"
value:"\x12\xa0\x0f\x9a\xd1D\xaf\x11%\x1e/%!\xdbNd\xf6/\x03\xbc\xbd\x870#.!\xabp\x9d\x8b~{\x8drE%\x1f\x00`i\xebzF\x16\x857m\xe4\x12;\x03ǝ\xe94Y\xde7\xbf\xefX^\x97\xcf15C\xa0L\x9f{\xbd\x92c\xd8-Q>\xbc\x9a<'\x97\xacA\x19\xe2\x92\x1avffL\xb7$`\xfe\x159S\xa4ȴB\xd7\xcej\xc0\xb1\x7f¸L\xe2p\x9a͖\x1d]\xc1Ԩ\xfa%\xe9\xc8md\xbc4~\xcd/`\xc3'\x0b\xa7\xba\x942tA\x93\xbc\xca\xf6\x87\x82s\xd6\xcf\x1c3'N\xe2S\x9b?\xacb\xb6\xfe\xdd6\xefm%\t\x12)\xc7\x14+OƖ:\xc8U顔\xa8\xady\xa5Ƅۯ\xee\x08:\x87\xa3M\x80\x07\xebђ\x88\x7f\xf2A\x07\x86}\x86\x94Z\xf9Ǡ4+\x1ag\"\x9f&\xb85\xbb\xe8\xce\x15\x97\xd6*\xb4\xa1\xe5\\1\xff\x95\xeeO]\xffݫg\x1d\xf9\xb7\x1a\xfdRf+\x90\x19\x96\xca\x14=\xbc\x95\xdc;\xef\x93\xc5Q\xae\x9c!\xcf'\x83)\xb3s\x81|o\xa7zo\x0b\xec\xc5\x14\xc6S:\x1b\x8c\xbe\xd2'\xc0\xd6d\x96pIF\x97\xa6l\x88\x0e\xa7\x1e\x02\r\x01L\x9c\xfb\rT\xef\xfffo\x8b^\xa6\xfcd+\x88\x7f\xe8E\x06\x93\xcc/Е\xb7\xf7\x17\x8c\xa5\xaf\x9f\x1bXZh\x985\x1cV\xfe\xce\xd4\x01\x98\x1f\xbe\x0fG\xc3%:\x8b\xfcg\x9c*pXn@Y\xd6\xd7\xd6\xe9X\x0e\xc3\x1d\xd5ݫ]\xeb\x1cW\xe7K\xbf5a3\xb2\x13\xd80}V1h\xa6o\x06`W\xc4?|\xfc\xd7\xe3\x9cc1t\xb2\xae\xf6N\xa0\x91pys+e\xe70\xf4\xe4hNy\xa6I\x95\xfb]\xd2p\x9c\x90^C%\x96օ\xadR۸\xbd%\xf4\xa2\xed\xe7\x7f\x93B(\xeaUjG\x19\r\xd0ɾ\x19\xe7\xc9\xd9}\xe4b\xf6\x12*\x05gy8\x15\xb5ι)\xaa\xe6\xe6\xc9ѕ\x17H$8b\xc6\xe3Ǘ\x9e\x94o\x9f)\x1c\xee]l\xb4\xc4P\xe0\xf9\x89\x15\xd0k\xdcH`\xb0\x92~y匳\xa3\xaf\x82-r\x0eY\x80\xc3;\xe0\x14\x04\xb4\x17v\xe2\xd1EV\x13%Q\x14\xee\xf2{1*or\x8c\x9c\xcf\x1cp|\x9b\x07\x85\x8d/\nF\xd3\x07Ҩ\x9af\xe290\x95\x80\x18\x10\x80V\x0b\x02w)\x8cU\x15\xa2\xa1\rn\x0e\x84\x04\x96\x97\x18\x1d\x00\xe0\xdf\xfe\xbcu\x9eI\xa5\x95a\x12ۍ\xd7Rr\xd4\xfa\xaa\x86\x18\x8a\xbdW\xdf\xfa\xb8N\x05\x92߶\x15¸\xa3t\xdbE/\x90\xeb\x81Ycx\xe9+\xb5\xf2\x05,ddz3k\x8b\xaf\x0bL\xd0ށ\xady\xc1yw\x80\x10\xd1ə\xedĤ\xc08\x0c\xb8\x1e\xc1\x0c/@\xf6\xf2\x1d\xd4\xfel詣\x98|r\xd8\x00[\x9c\x96\xf3\xabbx\x10\x16\x8c\xdcr*\x0b\xf9\x1f\xea\x84\xfcw|-\x86\xbf\t4\xea\xf0H\xbf\x95z.q\x02$\x8ei\x92J\xc1\x1b\x05\x94\nD\\\xb5\x1aD\x82\x1f\x17\xcfh\x8acA\xd6\x17\xe4\xa0\t矙\xddc$\xb6X@\xb9P\x16;^\x9a\xf1\xb3>\x18\xe7\x14\xb5rU\x86\x9d]q\xa6\xf5\xa4\xa4GkVw\xd7\xebv\x18\x13Q\xb2H8-\x83\x97\xbbM\xc5\xe8+@X/\xbe\xf0\xef\xec:\xe3\xa8N.a\x16\x0f\xb9\x00\xc9l^v\xac\x99\xebf9'%f\xe40\xe5\x934d\x9d-\x9eٙ\xff\xc2J\xbb+!ĻA\x16\xe9\x881\x9c\xab\x80\xfe\xd3\x10\xf1 \x8bn\xcf\xf0ょE5\x96U\xb5\x98(\x967\xfb\xa7\xa8B\xfb\xaaG\xaaz\x0c\x16_\xb8\x94\x93\x983\xfa\xe0W\x19\xc4gH\xef2\xe2FE\xfb\xc0\x8e@\"\x19\xb3\x87\"\xfe7p\xfb\xc9e\x9aoYh\xac-Uz\xeb\x8a\xf7\xaa|\xeb.\x91\x96w\tv\x98\xa4\xefN*\xa4\xfc\xd2s\xcbT\xa4\xbe\x16٤\x18$g\xc9 m \x19\xfd\x83\xf58\x94\xd1\xd1x\xbcȁM^\x9e\x1b\xf8\xacec\xf6$HQ\\w\xc1,\n\xf2Ό\xb0\xca\xc1(\xf0\xa12.\x9a\x82\xcc\xdb\xd0}}Hv`iU\x91\xcb^\x1e\\\xe2\xa4z\xe2gkˣ\\\xf7\xf3L+qc\x90멺t\xfd\xb9\x08\xce7\raA\x1f\xa3\xb5\xdf\x7fZ\x07O\xfa\xb1\x92\x9aaH\x15\x10r\x80!\xadt\xa9{\x0f܌JP\x7ft\x198\x95\xbc\x85\xa2D\xe3֊\r\x94\xdcg\x1a\x13\xff\xb72$\x97\xee\x9c;#Ɓij\x93\xce^+\x14\xb5Z\x05n\xdaR\xd1\xd9z\xea\xf9\t\xd0^\xf