当前位置:网站首页>[eosio] eos/wax signature error is_ Canonical (c): signature is not canonical
[eosio] eos/wax signature error is_ Canonical (c): signature is not canonical
2022-06-25 22:59:00 【encoderlee】
review
《【 Blockchain 】 Publish a pure Python Realized EOSIO WAX SDK》
In the previous post , We re implemented a lightweight EOSIO SDK, But it took a while , It is found that sometimes transactions are submitted to EOS/WAX Online RPC Node time , The following error will be returned :
{“code”:500,“message”:“Internal Service Error”,“error”:{“code”:10,“name”:“assert_exception”,“what”:“Assert Exception”,“details”:[{“message”:“is_canonical( c ): signature is not canonical”,“file”:“elliptic_secp256k1.cpp”,“line_number”:164,“method”:“public_key”}]}}
Probably because the signature is not standard ,R or S Overvalued
Specification signature
The canonical signature is actually in BTC It is stipulated in :
【Low S values in signatures】:https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Low_S_values_in_signatures
BTC in bip62 Specifies the in the signature S The value cannot be greater than N/2, Because for a standard R Values and S value ,(R, S)、(N-R, S)、(R, N-S)、(N-R, N-S) Are legal signature values , If it is not constrained , It can lead to a problem , For the same transaction , There are four legal signature results , When your transaction is submitted to the Internet , A malicious attacker can use your signature (R, S), Generate an identical transaction , With signature (N-R, S), Replay attack (Replay Attacks).
The result was that your deal was for B Jun transfer 500 Coins , After being replayed by a malicious person , It will turn into two transactions , Repeat to B Jun transfer 500 Two coins , And suffer losses .
actually , Just specification R or S Less than N/2 To avoid the problem , But in the EOSIO in , This specification is more stringent :
https://steemit.com/steem/@dantheman/steem-and-bitshares-cryptographic-security-update
EOSIO requirement R and S Both must be less than at the same time N/2 Talent
Troubleshoot problems
our 【eosapi】 The code of the signature part , The reference is 【ueosio】, Let's see is_canonical() The implementation of the :
def is_canonical(r, s):
C = int((2 ** 256 - 1) / 2)
return r <= C and s <= C
No problem , Signature is 256 Bit ,N by 256 The maximum number of digits 2 ** 256 - 1, The code checks R and S All less than N/2
What is it for? EOS RPC The server still reports an error ?
The best way to solve the problem is to look at the source code
The returned error message has told us :
{“message”:“is_canonical( c ): signature is not canonical”,“file”:“elliptic_secp256k1.cpp”,“line_number”:164,“method”:“public_key”}
The mistake comes from 【elliptic_secp256k1.cpp】 Of the 164 That's ok , So we were EOSIO official github Find this line of code in , And find 【is_canonical】 The implementation of this function :
https://github.com/EOSIO/fc/blob/master/src/crypto/elliptic_common.cpp
bool public_key::is_canonical( const compact_signature& c ) {
return !(c.data[1] & 0x80)
&& !(c.data[1] == 0 && !(c.data[2] & 0x80))
&& !(c.data[33] & 0x80)
&& !(c.data[33] == 0 && !(c.data[34] & 0x80));
}
Then the case was solved , It turns out that it not only requires R and S All less than N/2, Also require R and S Are greater than or equal to (2 ** (256-8) - 1) / 2
Understand the principles
First, explain how to understand this algorithm , First compact_signature& c What is it? ,compact_signature& c Signature data , Let's see 【ueosio】 How to generate this signature :
def sign_hash(h, pk):
nonce = 0
while True:
v, r, s = ecdsa_raw_sign_nonce(h, pk, nonce)
if is_canonical(r, s):
signature = '00%02x%064x%064x' % (v, r, s)
break
nonce += 1
sig = DataStream(bytes.fromhex(signature)).unpack_signature()
return sig
This 【signature】 It's actually V / R / S It's stitched together , altogether 66 Bytes , At the beginning ‘\x00’ Indicates the signature type , Omit to remove , Finally, the server resolves compact_signature& c The actual is V / R / S Put it together 65 Bytes , among V Occupy 1 Bytes ,R and S Accounting for 32 byte , Because the signature is 256 Bit .
So in 【is_canonical】 in ,c.data[1] Refers to R The highest byte of the value ( high 8 position ),c.data[33] Refers to S The highest byte of the value ( high 8 position )
that
c.data[1] & 0x80
What does that mean ?
First c.data[1] yes 1 Bytes ,0x80 What is the binary of , yes 10000000
c.data[1] Place and place 0x80, When the result is True ? Of course it's a request c.data[1] The highest bit of binary is also 1 When , The expression is True, When c.data[1] The highest binary bit of is 0 When , Expression return False
c.data[1] The highest binary bit of is 1 Words , that c.data[1] At the very least >= 0x80, c.data[1] The highest binary bit of is 0 Words , that c.data[1] must < 0x80
So this bitwise and expression is actually equivalent to
c.data[1] >= 128
therefore
!(c.data[1] & 0x80)
Is actually equivalent to
c.data[1] < 128
And one 32 Bytes of 256 The highest byte of bits ( high 8 position ) Less than 128 What does that mean ?
First , The maximum value of a byte is 255, Less than 128 Is less than half of the maximum value represented by this byte
And one 32 The highest byte of the number of bytes is less than 128, It means this 32 Byte number , Less than 32 Half the maximum value that a byte can represent , That is less than N/2 Well
So go around , The meaning of this code is still to ask R and S All less than N/2
But beyond that , It also adds two conditions :
&& !(c.data[1] == 0 && !(c.data[2] & 0x80))
&& !(c.data[33] == 0 && !(c.data[34] & 0x80));
Does that mean , R If the highest byte of is equal to 0 Words ,R The next highest byte of cannot be less than 128 Well ,S It's worth the same
and R The next highest byte of cannot be less than 128, Doesn't that mean asking R Greater than or equal to (2 ** (256-8) - 1) / 2
solve
therefore ,【ueosio】 Of 【is_canonical】 In theory, the function can be changed in this way :
def is_canonical(r, s):
C1 = int((2 ** 256 - 1) / 2)
C2 = int((2 ** (256-8) - 1) / 2)
return C2 <= r < C1 and C2 <= s < C1
Of course , The most rigorous change is to be completely consistent with EOSIO The official code is consistent , Finally, we changed it like this :
def is_canonical(c):
return not (c[1] & 0x80) \
and not (c[1] == 0 and not (c[2] & 0x80)) \
and not (c[33] & 0x80) \
and not (c[33] == 0 and not (c[34] & 0x80))
And the code has been submitted for update :
https://github.com/encoderlee/eosapi/commit/5ffd1235dd938cc8836be58f9f12622e7f3d08ae
Please update in time , To avoid this problem :
pip install --upgrade eosapi
Digression
I want to refer to our signature code 【ueosio】, Without reference to 【eospy】?
In fact, the main problem is performance , The same deal ,【eospy】 Signing takes time 20ms, and 【ueosio】 Time consuming only 2ms, Difference between 10 Twice as many !!!
20ms What is the concept ? My computer room from here to Shanghai Telecom is delayed 20ms Not even , If you submit a transaction more slowly than others 20ms, How can you rob others when you are a Trading Robot .
【eospy】 The signature library used internally is 【ecdsa】
and
【ueosio】 The signature library used internally is 【cryptos】
Logically speaking 【ecdsa】 Than 【cryptos】 More popular , It is also more perfect , and 【ecdsa】 The claimed test data is not so straying , So it's probably 【eospy】 The use of posture problems caused by the slow
【cryptos】 stay github Upper star Although not so much , however !
【cryptos】 stay github The project name on is 【pybitcointools】, Its original version was the founder of Ethereum V God himself wrote , later V God has no time and energy to maintain , It is left to the open source community , See here for details :
https://github.com/vbuterin/pybitcointools
I really don’t have time to maintain this library further. If you want to fork it or use it despite lack of maintenance, feel free to clone locally and revert one commit.
This externally-maintained fork looks good though I did not personally
write it so can’t vouch for security:
https://github.com/primal100/pybitcointools
Apart from efficiency , Once again proved our 【eosapi】 choice V Divine 【cryptos】 Implementing the underlying signature algorithm is the right choice !
Exchange and discussion

边栏推荐
- EVC, VVC, lcevc test: how about the performance of the latest MPEG codec?
- Unity technical manual - particle emission and life cycle velocity sub module
- Tiger Dao VC products are officially launched, a powerful supplement to seektiger ecology
- Glory launched the points mall to support the exchange of various glory products
- Which PHP open source works deserve attention
- 2022年河南省第一届职业技能大赛网络安全项目试题
- This 110 year old "longevity" enterprise has been planning for the next century
- 2022-2028 global DC linear variable differential transformer (LVDT) industry survey and trend analysis report
- How to design a complex business system? From the understanding of domain design, cloud native, micro service, and middle platform
- MATLAB Programming Notes
猜你喜欢

ES6-- 模板字符串、对象的简化写法、箭头函数

2022-2028 global web and browser isolation platform industry research and trend analysis report
This 110 year old "longevity" enterprise has been planning for the next century

Nacos source code analysis 01 code structure
Interview shock 23: talk about thread life cycle and transformation process?

记|一次exists关键字的学习记录

2022年河南省第一届职业技能大赛网络安全项目试题

2022-2028 global vacuum jacket system industry survey and trend analysis report

Relinearization in homomorphic encryption (ckks)

实战:typora里面如何快捷改变字体颜色(博客分享-完美)-2022.6.25(已解决)
随机推荐
OSPF - detailed explanation of GRE tunnel (including configuration command)
Jz-064- maximum value of sliding window
Relinearization in homomorphic encryption (ckks)
Online crudhasone Association query reports an error unabletouseinternalvariable:list
2022年中职组网络安全新赛题
2022-2028 global transmission type photoelectric circuit breaker industry research and trend analysis report
2022-2028 global selective laser sintering service industry research and trend analysis report
What are the channels for Internet advertising to gain customers?
Report on development status and prospects of global and Chinese coating industry strategic planning proposal 2022-2028
Hotspot JVM "01" class loading, linking and initialization
Simple and easy-to-use cache library gcache
Reasons why MySQL cannot be connected externally after installing MySQL database on ECs and Solutions
Facing the "industry, University and research" gap in AI talent training, how can shengteng AI enrich the black land of industrial talents?
Thinking while walking
多模态数据也能进行MAE?伯克利&谷歌提出M3AE,在图像和文本数据上进行MAE!最优掩蔽率可达75%,显著高于BERT的15%...
简单好用的缓存库 gcache
[dynamic programming] longest palindrome substring thinking about dynamic transfer cycle sequence
Another breakthrough! Alibaba cloud enters the Gartner cloud AI developer service Challenger quadrant
Research and Analysis on the current situation of China's magnetic detector Market and forecast report on its development prospect (2022)
NRM source switching tool