@dedis/kyber
Version:
A typescript implementation of Kyber interfaces
82 lines (81 loc) • 2.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const crypto_browserify_1 = require("crypto-browserify");
/**
* Sign computes a Schnorr signature over the given message.
* @param suite the group to use to sign
* @param privateKey the private key
* @param message the message that will be signed
* @returns the signature as a buffer
*/
function sign(suite, privateKey, message) {
// generate r & R
const r = suite.scalar().pick();
const R = suite.point().mul(r, null);
const buffR = R.marshalBinary();
// generate public key
const pub = suite.point().mul(privateKey, null);
// generate challenge
const challenge = hashSchnorr(suite, buffR, pub.marshalBinary(), message);
// generate signature
const s = suite.scalar().mul(privateKey, challenge);
s.add(s, r);
// concatenate R || s
const buffS = s.marshalBinary();
const buffSig = Buffer.allocUnsafe(buffR.length + buffS.length);
buffR.copy(buffSig);
buffS.copy(buffSig, buffR.length);
return buffSig;
}
exports.sign = sign;
/**
* Verify verifies if the signature of the message is valid under the given public
* key.
* @param suite the group to use to verify
* @param publicKey the public key
* @param message the message signed
* @param signature the signature of the message
* @returns true when the signature is correct for the given message and public key
*/
function verify(suite, publicKey, message, signature) {
// check the signature size
const plen = suite.pointLen();
const slen = suite.scalarLen();
const totalSize = plen + slen;
if (signature.length !== totalSize) {
return false;
}
// unmarshal R || s
const buffR = signature.slice(0, plen);
const R = suite.point();
R.unmarshalBinary(buffR);
const buffs = signature.slice(plen, signature.length);
const s = suite.scalar();
s.unmarshalBinary(buffs);
// recompute challenge = H(R || P || M)
const buffPub = publicKey.marshalBinary();
const challenge = hashSchnorr(suite, buffR, buffPub, message);
// compute sG
const left = suite.point().mul(s, null);
// compute R + challenge * Public
const right = suite.point().mul(challenge, publicKey);
right.add(right, R);
return right.equals(left);
}
exports.verify = verify;
/**
* hashSchnorr returns a scalar out of hashing the given inputs.
* @param suite the group to use to create the scalar
* @param inputs the different inputs as buffer
* @returns the scalar resulting from the hash of the inputs
*/
function hashSchnorr(suite, ...inputs) {
const h = crypto_browserify_1.createHash("sha512");
for (const i of inputs) {
h.update(i);
}
const scalar = suite.scalar();
scalar.setBytes(h.digest());
return scalar;
}
exports.hashSchnorr = hashSchnorr;