Skip to main content
Version: 11.x

Class: Falcon512Signer

Defined in: Falcon512Signer.ts:49

Signer for the S2morrow Falcon-512 account (post-quantum signature), in pure TypeScript.

Falcon-512 is a signature scheme built on lattices, designed to resist attacks by quantum computers. The S2morrow account (https://github.com/feltroidprime/s2morrow) verifies it on-chain, on a Poseidon hash of the transaction. A signature is 61 felts.

Fees: the on-chain verification costs much more L2 gas than an ECDSA one. By default, the fee estimates of Account skip the validation of the signature (skipValidate: true), so they leave out this cost: pass { skipValidate: false } to execute, deployAccount and declare.

Status:

  • This is Falcon as submitted to Round 3 of the NIST post-quantum standardization, not FN-DSA (FIPS 206). FN-DSA is not final yet, and will most likely be incompatible with it.
  • The Falcon code is a patched copy of @noble/post-quantum 0.7.1, kept until noble publishes the API this signer needs. noble has no independent audit: its author audited version 0.6.1 (April 2026).
  • Signing is not constant-time: do not sign where an attacker can measure its timing closely.
  • Only V3 transactions are supported.

Implements​

  • SignerInterface

Constructors​

Constructor​

new Falcon512Signer(secretKey): Falcon512Signer

Defined in: Falcon512Signer.ts:72

Builds a signer from a NIST Falcon-512 secret key. The key is fully checked, then copied: the signer keeps its own copy, in a private field.

Parameters​

secretKey​

string | Uint8Array<ArrayBufferLike>

NIST Falcon-512 secret key (1281 bytes), Uint8Array or hex string. Prefer a Uint8Array: a string cannot be wiped from memory.

Returns​

Falcon512Signer

Throws​

when the secret key is invalid

Example​

const { secretKey } = falcon512.generateKeyPair();
const mySigner = new Falcon512Signer(secretKey);
new Falcon512Signer(new Uint8Array(1281));
// throws Error("Falcon512: invalid secret key header")

Methods​

fromFalconRs()​

static fromFalconRs(secretKey): Falcon512Signer

Defined in: Falcon512Signer.ts:104

Builds a signer from a falcon-rs secret key (3584 bytes), converted to the NIST format.

Warning: falcon-rs derives the seed of its sampler from the public salt of each signature, so the signatures it produced may leak information about the secret key. Use this for continuity only; for real funds, generate a new key with falcon512.generateKeyPair. The S2morrow account cannot change its key: a new key means a new account.

Parameters​

secretKey​

string | Uint8Array<ArrayBufferLike>

the falcon-rs secret key (3584 bytes), or its hex string

Returns​

Falcon512Signer

a signer that holds the same key, in the NIST format

Throws​

when the falcon-rs secret key is invalid

Example​

const mySigner = Falcon512Signer.fromFalconRs(falconRsSecretKey); // 3584 bytes, from falcon-rs
const result = mySigner.getPackedPublicKey();
// result = ['0xb2cf4f8b3c6f60cc662f438970ad34017e260c52d7911297a42811ce3cea2b', …] (29 felts)

getPubKey()​

getPubKey(): Promise<string>

Defined in: Falcon512Signer.ts:124

NIST Falcon-512 public key (897 bytes), as a hex string.

Returns​

Promise<string>

the public key: 0x, then 1794 hex digits

Example​

const { secretKey } = falcon512.generateKeyPair();
const mySigner = new Falcon512Signer(secretKey);
const result = await mySigner.getPubKey();
// result = '0x09…' (1796 characters; 09 is the header of the format)

Implementation of​

starknet.SignerInterface.getPubKey


getPackedPublicKey()​

getPackedPublicKey(): string[]

Defined in: Falcon512Signer.ts:139

The 29 felts of the account constructor argument pk_packed.

Returns​

string[]

the 29 felts, as hex strings (a new array at each call)

Example​

const { secretKey } = falcon512.generateKeyPair();
const mySigner = new Falcon512Signer(secretKey);
const result = mySigner.getPackedPublicKey();
// result = ['0x…', …] (29 felts)

signMessage()​

signMessage(typedData, accountAddress): Promise<Signature>

Defined in: Falcon512Signer.ts:154

Signs a SNIP-12 message (TypedData) for off-chain use.

Parameters​

typedData​

TypedData

the message to sign

accountAddress​

string

address of the account that signs the message

Returns​

Promise<Signature>

the 61 felts of the signature, as hex strings

Example​

const result = await mySigner.signMessage(myTypedData, accountAddress);
// result = ['0x…', …] (61 felts, random salt); result[29] = '0x2' (salt length)

Implementation of​

starknet.SignerInterface.signMessage


signTransaction()​

signTransaction(transactions, details): Promise<Signature>

Defined in: Falcon512Signer.ts:197

Signs an INVOKE transaction (V3 only).

Parameters​

transactions​

Call[]

the calls of the transaction

details​

InvocationsSignerDetails

the details needed to hash the transaction

Returns​

Promise<Signature>

the 61 felts of the signature, as hex strings

Throws​

when the transaction is not V3

Example​

const calls: Call[] = [
{
contractAddress: '0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',
entrypoint: 'transfer',
calldata: ['0x123', '1000', '0'],
},
];
const details: InvocationsSignerDetails = {
walletAddress: accountAddress,
chainId: constants.StarknetChainId.SN_SEPOLIA,
cairoVersion: '1',
version: '0x3',
nonce: 1,
resourceBounds: {
l1_gas: { max_amount: 0n, max_price_per_unit: 50000000000000n },
l2_gas: { max_amount: 40000000n, max_price_per_unit: 20000000000n },
l1_data_gas: { max_amount: 1000n, max_price_per_unit: 100000n },
},
tip: 0,
paymasterData: [],
accountDeploymentData: [],
nonceDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
feeDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
};
const result = await mySigner.signTransaction(calls, details);
// result = ['0x…', …] (61 felts)

Implementation of​

starknet.SignerInterface.signTransaction


signDeployAccountTransaction()​

signDeployAccountTransaction(details): Promise<Signature>

Defined in: Falcon512Signer.ts:250

Signs the DEPLOY_ACCOUNT transaction of a Falcon-512 account (V3 only).

Parameters​

details​

V3DeployAccountSignerDetails

the details needed to hash the transaction

Returns​

Promise<Signature>

the 61 felts of the signature, as hex strings

Throws​

when the transaction is not V3

Example​

const packedPublicKey = mySigner.getPackedPublicKey();
const classHash = '0x37c7626b50ba517835c9556b53bce57cb6633704bb702f8c2f13a44cf151d5';
const salt = packedPublicKey[0];
const details: DeployAccountSignerDetails = {
classHash,
constructorCalldata: packedPublicKey,
addressSalt: salt,
contractAddress: hash.calculateContractAddressFromHash(salt, classHash, packedPublicKey, 0),
chainId: constants.StarknetChainId.SN_SEPOLIA,
version: '0x3',
nonce: 0,
resourceBounds: {
l1_gas: { max_amount: 0n, max_price_per_unit: 50000000000000n },
l2_gas: { max_amount: 60000000n, max_price_per_unit: 20000000000n },
l1_data_gas: { max_amount: 1000n, max_price_per_unit: 100000n },
},
tip: 0,
paymasterData: [],
accountDeploymentData: [],
nonceDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
feeDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
};
const result = await mySigner.signDeployAccountTransaction(details);
// result = ['0x…', …] (61 felts)

Implementation of​

starknet.SignerInterface.signDeployAccountTransaction


signDeclareTransaction()​

signDeclareTransaction(details): Promise<Signature>

Defined in: Falcon512Signer.ts:295

Signs a DECLARE transaction (V3 only).

Parameters​

details​

V3DeclareSignerDetails

the details needed to hash the transaction

Returns​

Promise<Signature>

the 61 felts of the signature, as hex strings

Throws​

when the transaction is not V3

Example​

const details: DeclareSignerDetails = {
senderAddress: accountAddress,
classHash: '0x37c7626b50ba517835c9556b53bce57cb6633704bb702f8c2f13a44cf151d5',
compiledClassHash: '0x1f2afb8ae690b84f4b7acfde52fbd2e5a1dc0c910ed898a778dc1ad3339e5c5',
chainId: constants.StarknetChainId.SN_SEPOLIA,
version: '0x3',
nonce: 2,
resourceBounds: {
l1_gas: { max_amount: 0n, max_price_per_unit: 50000000000000n },
l2_gas: { max_amount: 80000000n, max_price_per_unit: 20000000000n },
l1_data_gas: { max_amount: 1000n, max_price_per_unit: 100000n },
},
tip: 0,
paymasterData: [],
accountDeploymentData: [],
nonceDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
feeDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
};
const result = await mySigner.signDeclareTransaction(details);
// result = ['0x…', …] (61 felts)

Implementation of​

starknet.SignerInterface.signDeclareTransaction