elliptic-solidity
Version:
Elliptic curve implementation in solidity; includes secp256r1
115 lines (77 loc) • 3.58 kB
JavaScript
// Tilman Drerup (2018).
// Test for EllipticCurve contract in SECP256R1 parametrization.
const SECP256R1 = artifacts.require("./EllipticCurve.sol");
const assertRevert = require('../helpers/assertRevert');
const bigNumber = require('bignumber.js');
const crypto = require('crypto');
const ecPem = require('ec-pem');
const ethereumJSUtil = require('ethereumjs-util');
contract('SECP256R1', async (accounts) => {
let curve;
let messageHash;
let publicKey;
let signature;
beforeEach(async () => {
// Create contract.
curve = await SECP256R1.new();
// Create curve object for key and signature generation.
var prime256v1 = crypto.createECDH('prime256v1');
prime256v1.generateKeys();
// Reformat keys.
var pemFormattedKeyPair = ecPem(prime256v1, 'prime256v1');
publicKey = [
'0x' + prime256v1.getPublicKey('hex').slice(2, 66),
'0x' + prime256v1.getPublicKey('hex').slice(-64)
];
// Create random message and sha256-hash it.
var message = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
messageHash = ethereumJSUtil.bufferToHex(ethereumJSUtil.sha256(message));
// Create signature.
var signer = crypto.createSign('RSA-SHA256');
signer.update(message);
var sigString = signer.sign(pemFormattedKeyPair.encodePrivateKey(), 'hex');
// Reformat signature / extract coordinates.
var xlength = 2 * ('0x' + sigString.slice(6, 8));
var sigString = sigString.slice(8)
signature = [
'0x' + sigString.slice(0, xlength),
'0x' + sigString.slice(xlength + 4)
];
});
it('confirm that a valid point is on the curve', async() => {
let x = "0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
let y = "0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
var onCurve = await curve.isOnCurve(x, y);
assert.equal(onCurve, true);
});
it('reject that an invalid point is on the curve', async() => {
let x = "0x3B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
let y = "0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
var onCurve = await curve.isOnCurve(x, y);
assert.equal(onCurve, false);
});
it('confirm valid signature (#1)', async () => {
var result = await curve.validateSignature.call(messageHash, signature, publicKey);
assert.equal(result, true);
});
it('confirm valid signature (#2)', async () => {
var result = await curve.validateSignature.call(messageHash, signature, publicKey);
assert.equal(result, true);
});
it('reject signature with flipped public key coordinates ([x,y] >> [y,x])', async () => {
var flippedPublicKey = [publicKey[1], publicKey[0]];
var result = await curve.validateSignature.call(messageHash, signature, flippedPublicKey);
assert.equal(result, false);
});
it('reject signature with flipped signature values ([r,s] >> [s,r])', async () => {
var flippedSignature = [signature[1], signature[0]];
var result = await curve.validateSignature.call(messageHash, flippedSignature, publicKey);
assert.equal(result, false);
});
it('reject signature with invalid message hash', async () => {
var invalidMessage = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
var invalidMessageHash = ethereumJSUtil.bufferToHex(ethereumJSUtil.sha256(invalidMessage));
var result = await curve.validateSignature.call(invalidMessageHash, signature, publicKey);
assert.equal(result, false);
});
});