testSchnorSignature.js 3.71 KB
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);
    });	   
});