Skip to content

Instantly share code, notes, and snippets.

@arik-so
Last active November 5, 2022 17:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arik-so/717a40a21c8e38e6bbabd0c451d62b30 to your computer and use it in GitHub Desktop.
Save arik-so/717a40a21c8e38e6bbabd0c451d62b30 to your computer and use it in GitHub Desktop.
Schnorr Experimenting
const ecurve = require('ecurve');
let secp256k1 = ecurve.getCurveByName('secp256k1');
const BigInteger = require('bigi');
const crypto = require('crypto');
const calculateHash = (R, P, message) => {
const hashPreimage = Buffer.concat([R.getEncoded(true), P.getEncoded(true), Buffer.from(message, 'utf-8')]);
return BigInteger.fromHex(crypto.createHash('sha256').update(hashPreimage).digest('hex')).mod(secp256k1.n);
};
const signMessage = (message, privkey) => {
/**
* 1) generate random integer r
* 2) find its corresponding random point R on the curve
* 3) hash (R || P || message) = h
* 4) return s = r + h * privKey, R
*/
const r = BigInteger.fromHex(crypto.randomBytes(32).toString('hex')).mod(secp256k1.n);
const x = BigInteger.fromHex(privkey);
const generator = secp256k1.G;
const P = generator.multiply(x);
const R = generator.multiply(r);
const h = calculateHash(R, P, message);
const s = h.multiply(x).add(r).mod(secp256k1.n);
return [R, s];
};
const verifySignature = (message, pubkey, signature) => {
const s = signature[1];
const R = signature[0];
const P = ecurve.Point.decodeFrom(secp256k1, Buffer.from(pubkey, 'hex'));
const h = calculateHash(R, P, message);
const generator = secp256k1.G;
const calculatedPoint = P.multiply(h).add(R);
const restoredPoint = generator.multiply(s);
return calculatedPoint.getEncoded(true).equals(restoredPoint.getEncoded(true));
};
const pubkey = '0219877ed8cc48ed3ac0b4e0295aaecb3b00dc3c1c49049fc566780d054dec1986';
const privkey = 'e5d5ca46ab3fe61af6a001e02a5b979ee2c1f205c94804dd575aa6134de43ab3';
const message = 'Arik is rolling his own crypto';
const signature = signMessage(message, privkey);
const isValid = verifySignature(message, pubkey, signature);
console.log('Signature valid:', isValid);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment