椭圆曲线签名之区块链签名验证

对称加密

学过计算机的人都知道知名度rsa加密算法。它使用了两个数字相乘很容易,但是把一个大数字分解为素数却很难的这个原理,来实现对称加密。但是随着计算机的发展rsa的安全性越来越受到挑战。于是在bitcoin中一个叫做椭圆曲线算法的对称加密算法被使用,并且在长期实践中证明了其安全性。

椭圆曲线算法

椭圆曲线密码术是一种基于离散对数问题的非对称或公钥密码体系,如椭圆曲线上的加法和乘法运算。作为一种对称加密算法,椭圆曲线算法比ras算法用更小的公钥,实现更高的效率,实现了更高的安全性。

数字签名在比特币中有三种用途。

  1. 签名证明私钥的所有者,即资金所有者,已经授权支出这些资金。
  2. 授权证明是不可否认的 (不可否认性)
  3. 签名证明交易(或交易的具体部分)在签字之后没有也不能被任何人修改

算法介绍

这部分可以参考:精通以太坊 (中文版):https://www.bookstack.cn/read/ethereum_book-zh/spilt.6.4e6f5cb249c84882.md

算法

椭圆曲线算法实现

总的来说,首先要生成一个随机数根据K=k*P ,来确定私钥。
具体的在数字签名的时候,区块链使用的算法和正规的椭圆曲线算法有一定的差异。经过签名的消息是可以被分解为 r ,s的。只靠rs所反解的public key会有四组,不过实际上最常见的是2组,因为另外两种出现的概率很低很低。这篇文章有具体的说明:https://bitcoin.stackexchange.com/questions/38351/ecdsa-v-r-s-what-is-v

椭圆曲线算法签名实现

下面是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

public class Sign {

public static final String PERSONAL_MESSAGE_PREFIX = "\u0019Ethereum Signed Message:\n";

public static void RecoverAddress) {

String signature = "xxxx";

String address = "yyyy";
String message = "msg";

String prefix = PERSONAL_MESSAGE_PREFIX + message.length();
byte[] msgHash = Hash.sha3((prefix + message).getBytes());

byte[] signatureBytes = Numeric.hexStringToByteArray(signature);
byte v = signatureBytes[64];
if (v < 27) {
v += 27;
}

SignatureData sd =
new SignatureData(
v,
(byte[]) Arrays.copyOfRange(signatureBytes, 0, 32),
(byte[]) Arrays.copyOfRange(signatureBytes, 32, 64)
);

String addressRecovered = null;
boolean match = false;

// Iterate for each possible key to recover
for (int i = 0; i < 4; i++) {
BigInteger publicKey =
Sign.recoverFromSignature(
(byte) i,
new ECDSASignature(
new BigInteger(1, sd.getR()), new BigInteger(1, sd.getS())),
msgHash);

if (publicKey != null) {
addressRecovered = "0x" + Keys.getAddress(publicKey);

if (addressRecovered.equals(address)) {
match = true;
break;
}
}
}

if (addressRecovered.equals(address)) {
System.out.println(" recovered ... ");
}

if (match) {
System.out.println(" match ... ");
}

}
}


  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2020-2022 zzj
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信