@synet/core
Version:
Core cryptographic and identity primitives for Synet agents.
145 lines (144 loc) • 5.35 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.signMessage = signMessage;
exports.verifySignature = verifySignature;
const crypto = __importStar(require("node:crypto"));
/**
* Sign a message with a private key
* @param privateKey The private key in PEM format
* @param message The message to sign
* @returns The signature as a base64 string
* @throws {Error} If inputs are invalid or signing fails
*/
function signMessage(privateKey, message) {
try {
if (!privateKey || !message) {
throw new Error("Invalid input: privateKey and message are required");
}
const keyType = detectKeyType(privateKey);
if (keyType === "ed25519") {
// Use the modern API for Ed25519
const signature = crypto.sign(null, Buffer.from(message), {
key: privateKey,
format: "pem",
});
return signature.toString("base64");
}
// Use the traditional API for RSA
const sign = crypto.createSign("SHA256");
sign.update(message);
sign.end();
return sign.sign(privateKey, "base64");
}
catch (error) {
//console.error("Error signing message:", error);
if (error instanceof Error) {
throw new Error(`Failed to sign message: ${error.message}`);
}
throw new Error("Failed to sign message: Unknown error");
}
}
/**
* Verify a signature with a public key
* @param publicKey The public key in PEM format
* @param message The original message
* @param signature The signature to verify (base64 string)
* @returns True if the signature is valid, false otherwise
* @throws {Error} If inputs are invalid or signing fails
*/
function verifySignature(publicKey, message, signature) {
if (!publicKey || !message || !signature) {
throw new Error("Invalid input: publicKey, message and signature are required");
}
if (!publicKey.includes("-----BEGIN") || !publicKey.includes("-----END")) {
throw new Error("Invalid publicKey format: PEM format required");
}
try {
const keyType = detectKeyType(publicKey);
if (keyType === "ed25519") {
// Use the modern API for Ed25519
return crypto.verify(null, Buffer.from(message), {
key: publicKey,
format: "pem",
}, Buffer.from(signature, "base64"));
}
// Use the traditional API for RSA
const verify = crypto.createVerify("SHA256");
verify.update(message);
verify.end();
return verify.verify(publicKey, signature, "base64");
}
catch (error) {
console.error("Error signing message:", error);
if (error instanceof Error) {
throw new Error(`Failed to verify signature: ${error.message}`);
}
throw new Error("Failed to verify signature: Unknown error");
}
}
/**
* Detects the type of key based on its PEM content
* @param key The key in PEM format
* @returns 'rsa' or 'ed25519'
*/
function detectKeyType(key) {
try {
// For ED25519 keys in PKCS#8 format, the key is shorter
// RSA keys are much longer due to their modulus
const keyObj = crypto.createPublicKey({
key: key,
format: "pem",
});
const keyType = keyObj.asymmetricKeyType;
if (keyType === "ed25519") {
return "ed25519";
}
return "rsa";
}
catch (_e) {
// If we can't create a key object, try some heuristics
if (key.includes("BEGIN PRIVATE KEY") && key.length < 400) {
// ED25519 private keys are much shorter than RSA
return "ed25519";
}
if (key.includes("BEGIN PUBLIC KEY") && key.length < 300) {
// ED25519 public keys are much shorter than RSA
return "ed25519";
}
// Default to RSA as fallback
return "rsa";
}
}