mirror of
https://github.com/selfxyz/self.git
synced 2026-01-09 14:48:06 -05:00
100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
import * as forge from 'node-forge';
|
|
|
|
import { SignatureAlgorithm } from '@selfxyz/common/utils/types';
|
|
import { hexToDecimal } from '@selfxyz/common/utils/bytes';
|
|
import { bytesToBigDecimal } from '@selfxyz/common/utils/bytes';
|
|
import { getNAndK } from '@selfxyz/common/utils/passports/passport';
|
|
import { splitToWords } from '@selfxyz/common/utils/bytes';
|
|
|
|
export const generateMockRsaPssInputs = (
|
|
signatureAlgorithm: SignatureAlgorithm,
|
|
saltLength: number
|
|
) => {
|
|
const [sigAlg, hashAlgorithm, exponent, modulusLength] = signatureAlgorithm.split('_');
|
|
|
|
// Generate RSA key pair
|
|
const keypair = forge.pki.rsa.generateKeyPair({
|
|
bits: parseInt(modulusLength),
|
|
e: parseInt(exponent),
|
|
});
|
|
const message = 'helloworld';
|
|
|
|
// Create message hash
|
|
const md = forge.md[hashAlgorithm].create();
|
|
md.update(forge.util.binary.raw.encode(Buffer.from(message)));
|
|
const messageHash = md.digest().bytes();
|
|
const messageBits = Array.from(messageHash)
|
|
.map((char: string) => {
|
|
const byte = char.charCodeAt(0);
|
|
return Array.from({ length: 8 }, (_, i) => (byte >> (7 - i)) & 1);
|
|
})
|
|
.flat();
|
|
|
|
// Create PSS signature
|
|
const pss = forge.pss.create({
|
|
md: forge.md[hashAlgorithm].create(),
|
|
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
|
|
saltLength,
|
|
});
|
|
const signatureBytes = keypair.privateKey.sign(md, pss);
|
|
const signature = Array.from(signatureBytes, (c: string) => c.charCodeAt(0));
|
|
|
|
// Get modulus from public key
|
|
const modulus = keypair.publicKey.n.toString(16);
|
|
|
|
const { n, k } = getNAndK(signatureAlgorithm);
|
|
|
|
return {
|
|
signature: splitToWords(BigInt(bytesToBigDecimal(signature)), n, k),
|
|
modulus: splitToWords(BigInt(hexToDecimal(modulus)), n, k),
|
|
message: messageBits,
|
|
n,
|
|
k,
|
|
};
|
|
};
|
|
|
|
export const generateMalleableRsaPssInputs = (
|
|
signatureAlgorithm: SignatureAlgorithm,
|
|
saltLength: number
|
|
) => {
|
|
const [sigAlg, hashAlgorithm, exponent, modulusLength] = signatureAlgorithm.split('_');
|
|
|
|
// Generate RSA key pair
|
|
const keypair = forge.pki.rsa.generateKeyPair({
|
|
bits: parseInt(modulusLength),
|
|
e: parseInt(exponent),
|
|
});
|
|
|
|
const message = 'helloworld';
|
|
const md = forge.md[hashAlgorithm].create();
|
|
md.update(forge.util.binary.raw.encode(Buffer.from(message)));
|
|
const messageHash = md.digest().bytes();
|
|
|
|
// Create valid signature
|
|
const pss = forge.pss.create({
|
|
md: forge.md[hashAlgorithm].create(),
|
|
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
|
|
saltLength,
|
|
});
|
|
|
|
const signatureBytes = keypair.privateKey.sign(md, pss);
|
|
const signature = Array.from(signatureBytes, (c: string) => c.charCodeAt(0));
|
|
|
|
const modulus = BigInt('0x' + keypair.publicKey.n.toString(16));
|
|
const sigValue = BigInt(bytesToBigDecimal(signature));
|
|
const malleableValue = sigValue + modulus;
|
|
|
|
const { n, k } = getNAndK(signatureAlgorithm);
|
|
|
|
return {
|
|
signature: splitToWords(malleableValue, n, k),
|
|
modulus: splitToWords(modulus, n, k),
|
|
message: Array.from(messageHash)
|
|
.map((char: string) => {
|
|
const byte = char.charCodeAt(0);
|
|
return Array.from({ length: 8 }, (_, i) => (byte >> (7 - i)) & 1);
|
|
})
|
|
.flat(),
|
|
};
|
|
};
|