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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const { ethers } = require('hardhat');
const { expect } = require("chai");
const {BigNumber, utils} = require('ethers');
const elliptic = require('elliptic');
const ec = new elliptic.ec('secp256k1');
const abiCoder = new utils.AbiCoder();
describe ("Schnorr signature", () => {
let SchnorrSignature;
let schnorrSignature;
let p = BigNumber.from(ec.n.toString());
let r = BigNumber.from(utils.randomBytes(10));
let ecG =
[
"55066263022277343669578718895168534326250603453777594175500187360389116729240",
"32670510020758816978083085130507043184471273380659243275938904335757337482424"
];
let key = ec.genKeyPair();
let ecX = [key.getPublic().x.toString(), key.getPublic().y.toString()]; //publ_key
let x = BigNumber.from(key.getPrivate().toString()); //priv_key
let m = "message";
before (async () => {
SchnorrSignature = await ethers.getContractFactory("SchnorrSignature");
schnorrSignature = await SchnorrSignature.deploy();
await schnorrSignature.deployed();
});
it("Should be valid schnorr signature with random generated parametrs.", async () =>
{
//R = r*G
ecR = await schnorrSignature.eMul(r.toString(), ecG[0], ecG[1]);
ecR = [ecR[0].toString(), ecR[1].toString()];
// c = H(X, R, m)
c = BigNumber.from(utils.soliditySha256 // = encodePacked
(
["uint", "uint", "uint", "uint", "string"],
[ecX[0], ecX[1], ecR[0], ecR[1], m]
)
);
// s = r + c*x mod p
s = BigNumber.from(r).add(c.mul(x).mod(p)).mod(p);
expect(await schnorrSignature.SchnorrSignatureVerify(m, ecX, ecR, s)).to.equal(true);
});
it ("Should be invalid with a point not eliptic curve", async () => {
let ecFalse = [
"94550510891201125443038496712355512193683746567194802595430747803790456451800",
"100658497413695518730530153947607016384927173293555182183697767262819897530139"
];
let strToHash = abiCoder.encode(["uint", "uint", "uint", "uint", "string"],[ecX[0], ecX[1], ecFalse[0], ecFalse[1], m]);
c = BigNumber.from(utils.sha256(strToHash));
s = r.add(c.mul(x).mod(p)).mod(p);
await expect(
schnorrSignature.SchnorrSignatureVerify(m, ecX, ecFalse, s.toString())
).to.be.revertedWith("Invalid input parametrs to verify the Schnorr signature");
});
it("Should be invalid with false parametrs", async () => {
ecR = await schnorrSignature.eMul(r.toString(), ecG[0], ecG[1]);
ecR = [ecR[0].toString(), ecR[1].toString()];
let strToHash = abiCoder.encode(["uint", "uint", "uint", "uint", "string"],[ecX[0], ecX[1], ecR[0], ecR[1], m]);
c = BigNumber.from(utils.sha256(strToHash));
let sFalse = r.add(c.sub(x).mod(p)).mod(p);
expect(await schnorrSignature.SchnorrSignatureVerify(m, ecX, ecR, sFalse.toString())).to.equal(false);
});
it("Should be valid schnorr signature with client parametrs.", async () =>
{
[m, ecX, ecR, s] = [
"message",
[
"27986936006637619234751661742996901780685381967893915018229061434120181515483",
"70636065538896624272916187918422091966493606259112919971149037509751154464577"
],
[
"74580538217015729279249478019311517768049978358848055562761510406264032602856",
"109508452562322270947608736702231209675885566789465297663534653691453100979389"
],
"100046075731079052227894073046844253882820832097826080819312866318004576931689"
];
expect(await schnorrSignature.SchnorrSignatureVerify(m, ecX, ecR, s)).to.equal(true);
});
});