區塊鏈中的DCDSA 橢圓曲線數字簽名

2021-09-14 02:20:52 字數 3305 閱讀 9602

既然我們已經可以產生橢圓曲線金鑰對,我們接下來就用使用它來進行訊息的簽名和驗證。我所指的訊息是任何形式,無論是文字還是二進位制形式,只要它們有被驗證合法性的需要。特別的是,bitcoin客戶端通過簽名來證明交易的有效性,反之,礦工則是通過驗證這樣的簽名,來批准並廣播合法的交易。

橢圓曲線簽名演算法就是ecdsa(elliptic-curve digital signature algorithm).在ecdsa中,各方必須約定乙個共同的雜湊函式h, 因為我們將要簽名的物件是h(訊息)下面的案例中,我們簽名的物件是sha-256摘要。但bitcoin中指定的h函式是hash256,也就是指雙重sha-256

簽名第一步把我們的訊息存入檔案,命名ex-message.txt

this is a very confidential message
之後,我們用私鑰對其sha-256摘要進行簽名。

$ openssl dgst -sha256 -sign ec-priv.pem ex-message.txt >ex-signature.der
ex-signature.der檔案是簽名的der格式。openssl使用der編碼任何二進位制輸出,但這裡我們忽略這個細節。你不需要了解ecdsa簽名的語法,只需要記住它僅僅是一組的大數對(r,s)。

你可能會注意到,每一次你執行程式,簽名都發生變化,也就是說預設的簽名過程是不具有確定性的。這就給序列化區塊鏈交易時帶來了問題,因為簽名是交易位元組序列中的一部分,並且你一定知道txid是對交易進行雜湊得來的。因此,每當你簽名一筆交易txid就會隨之變化。這種行為也是造成交易可塑性的原因之一。

為了顯示十六進製制編碼的簽名,只需新增-hex引數。

$ openssl dgst -sha256 -hex -sign ec-priv.pem ex-message.txt
為了重用剛剛輸出的結果,最好使用hexdup已生成的der檔案。

$ hexdump ex-signature.der
驗證

無論什麼時候將合法訊息發布到網路,接收者都希望能夠得到乙個附件的簽名。在假設我們已經得到作者公鑰的情況下,無論是原訊息還是簽名,都必須作為驗證流程的輸入資料:

$ openssl dgst -sha256 -verify ec-pub.pem -signature ex-signature.der ex-message.txt
我們使用**來完成上文中在命令列中完成的同樣的工作。

簽名openssl使簽名流程變得簡單,這一部分可以在ex-ecdsa-sign.c中檢視。

uint8_t priv_bytes[32] = ;

const char message = "this is a very confidential message\n";

ec_key *key;

uint8_t digest[32];

ecdsa_sig *signature;

uint8_t *der, *der_copy;

size_t der_len;

...key = bbp_ec_new_keypair(priv_bytes);

bbp_sha256(digest, (uint8_t *)message, strlen(message));

signature = ecdsa_do_sign(digest, sizeof(digest), key);

ecdsa_sig是乙個簡單的結構,用於儲存上文所說的(r,s)對:

struct  ecdsa_sig;
使用i2d_ecdsa_sig函式,我們也可以得到der編碼的簽名:

der_len = ecdsa_size(key);

der = calloc(der_len, sizeof(uint8_t));

der_copy = der;

i2d_ecdsa_sig(signature, &der_copy);

驗證

驗證同樣很簡單,可以在ex-ecdsa-verify.c中檢視:

uint8_t pub_bytes[33] = ;

uint8_t der_bytes = ;

const char message = "this is a very confidential message\n";

ec_key *key;

const uint8_t *der_bytes_copy;

ecdsa_sig *signature;

uint8_t digest[32];

int verified;

...key = bbp_ec_new_pubkey(pub_bytes);

der_bytes_copy = der_bytes;

signature = d2i_ecdsa_sig(null, &der_bytes_copy, sizeof(der_bytes));

因為無法得到私鑰,我們利用使用下面的輔助函式將pub_bytes解碼為壓縮形式。

ec_key *bbp_ec_new_pubkey(const uint8_t *pub_bytes, size_t pub_len);
另一方面,der_bytes是簽名程式返回的der格式的簽名。我們將解碼der簽名到更方便的ecdsa_sig結構中,然後與訊息摘要比較進行驗證。

ecdsa_do_verify函式的返回值:

注意:使用ecdsa_verify可以跳過簽名的解碼過程,因為它需要的輸入值是der形式的簽名。

深入區塊鏈以太坊原始碼之橢圓曲線演算法

橢圓曲線加密演算法elliptic curve cryptosystem 安全性基礎 橢圓曲線群上的離散對數問題。目前,最好解決演算法仍是指數時間。一 橢圓曲線群是由兩部分組成 第一部分是m。區域f中有兩個數a,b m y 2 x 3 ax b 其中x,y屬於f f 第二部分為o點 無窮遠點 橢圓曲...

密碼學中的橢圓曲線

密碼學中的橢圓曲線 密碼學中的橢圓曲線不是定義在是實數域上的,我們要把橢圓曲線定義在有限域上 顧名思義,有限域是一種只有由有限個元素組成的域 域的概念是從我們的有理數,實數的運算中抽象出來的,嚴格的定義請參考近世代數方面的數。簡單的說,域中的元素同有理數一樣,有自己得加法 乘法 除法 單位元 1 零...

區塊鏈中的隨機數演算法

randao是一種非常簡單的隨機性方法,因此非常常用。一般的想法是,網路的參與者首先都是私下選擇乙個偽隨機數,然後向該私密選擇的數字提交承諾,都使用某種共識演算法就某些承諾達成一致,然後全部透露其選擇的數字,得出乙個 對顯示的數字達成共識,並對顯示的數字進行xor作為協議的輸出。它是不可 的,並且與...