@continuonai/rcan-ts 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -109,8 +109,9 @@ interface DelegationHop {
109
109
  scope: string;
110
110
  signature: string;
111
111
  }
112
+ /** RCAN v2.2: ML-DSA-65 is the only valid alg ("ml-dsa-65"). Ed25519 is deprecated. */
112
113
  interface SignatureBlock {
113
- alg: string;
114
+ alg: "ml-dsa-65";
114
115
  kid: string;
115
116
  sig: string;
116
117
  }
@@ -767,7 +768,7 @@ declare function makeTransparencyMessage(ruri: string, disclosure: string, deleg
767
768
  /** The RCAN spec version this SDK implements. */
768
769
  declare const SPEC_VERSION = "2.2.0";
769
770
  /** The SDK release version. */
770
- declare const SDK_VERSION = "1.2.0";
771
+ declare const SDK_VERSION = "1.2.1";
771
772
  /**
772
773
  * Validate version compatibility.
773
774
  *
@@ -1863,81 +1864,55 @@ declare function verifyM2mTrustedToken(token: string, targetRrn: string, options
1863
1864
  }): Promise<M2MTrustedClaims>;
1864
1865
 
1865
1866
  /**
1866
- * RCAN v2.2 Post-Quantum Hybrid Signing — ML-DSA-65 (NIST FIPS 204)
1867
- *
1868
- * Provides MLDSAKeyPair for post-quantum signing alongside the existing
1869
- * Ed25519 SignatureBlock. In hybrid mode a message carries both:
1870
- * - `signature` — Ed25519 SignatureBlock (backward-compat with v2.1)
1871
- * - `pqSig` — MLDSASignatureBlock (new in v2.2)
1867
+ * RCAN v2.2 ML-DSA-65 Signing (NIST FIPS 204)
1872
1868
  *
1873
- * Key sizes (ML-DSA-65, NIST security level 3):
1874
- * Public key: 1952 bytes
1875
- * Private key: 4032 bytes
1876
- * Signature: 3309 bytes
1869
+ * Ed25519 is deprecated. ML-DSA-65 is the ONLY signing algorithm.
1870
+ * All signed messages carry a ``signature`` block with ``alg: "ml-dsa-65"``.
1877
1871
  *
1878
1872
  * Requires: @noble/post-quantum (npm install @noble/post-quantum)
1879
1873
  *
1880
- * Spec: https://rcan.dev/spec#section-7-2
1874
+ * Spec: https://rcan.dev/spec/v2.2#section-7-2
1881
1875
  */
1882
1876
 
1883
- /** @deprecated use PQSignatureBlock */
1884
- type MLDSASignatureBlock = PQSignatureBlock;
1885
1877
  interface MLDSAKeyPairData {
1886
- /** Public key bytes (1952 bytes) */
1887
1878
  publicKey: Uint8Array;
1888
- /** Private key bytes (4032 bytes). Absent for verify-only key pairs. */
1889
1879
  secretKey?: Uint8Array;
1890
- /** 8-char hex key ID */
1891
1880
  keyId: string;
1892
1881
  }
1893
1882
  /**
1894
1883
  * An ML-DSA-65 (CRYSTALS-Dilithium, NIST FIPS 204) key pair.
1895
1884
  *
1896
- * Immutable value object. Build via {@link MLDSAKeyPair.generate} or
1897
- * {@link MLDSAKeyPair.fromPublicKey}.
1885
+ * This is the ONLY signing key type in RCAN v2.2+. Ed25519 is deprecated.
1898
1886
  */
1899
1887
  declare class MLDSAKeyPair {
1900
1888
  readonly keyId: string;
1901
1889
  readonly publicKey: Uint8Array;
1902
1890
  readonly secretKey: Uint8Array | undefined;
1903
1891
  private constructor();
1904
- /** Generate a new ML-DSA-65 key pair. */
1905
1892
  static generate(): Promise<MLDSAKeyPair>;
1906
- /** Build a verify-only key pair from raw public key bytes. */
1907
1893
  static fromPublicKey(publicKey: Uint8Array): Promise<MLDSAKeyPair>;
1908
- /** Build a full key pair from saved bytes (public + secret). */
1909
1894
  static fromKeyMaterial(publicKey: Uint8Array, secretKey: Uint8Array): Promise<MLDSAKeyPair>;
1910
1895
  get hasPrivateKey(): boolean;
1911
- /** Sign raw bytes; returns ML-DSA-65 signature (3309 bytes). */
1912
1896
  signBytes(data: Uint8Array): Promise<Uint8Array>;
1913
- /**
1914
- * Verify an ML-DSA-65 signature.
1915
- * @returns true if valid
1916
- * @throws {Error} on invalid signature
1917
- */
1918
1897
  verifyBytes(data: Uint8Array, signature: Uint8Array): Promise<void>;
1919
1898
  toString(): string;
1920
1899
  }
1921
1900
  /**
1922
- * Add an ML-DSA-65 signature (`pqSig`) to an RCAN message.
1923
- *
1924
- * This is the v2.2 hybrid complement to the existing Ed25519 signature.
1925
- * Call {@link signMessageEd25519} (or the existing signing path) first to set
1926
- * `signature`, then call this to append `pqSig`.
1901
+ * Sign an RCANMessage with ML-DSA-65 (the only signing algorithm in RCAN v2.2).
1927
1902
  *
1928
- * @param msg RCAN message (mutated in place sets `pqSig`)
1929
- * @param keypair ML-DSA-65 key pair with private key
1930
- * @returns The same message cast to include `pqSig`
1903
+ * Sets msg.signature = { alg: "ml-dsa-65", kid, sig }.
1931
1904
  */
1932
- declare function addPQSignature(msg: RCANMessage, keypair: MLDSAKeyPair): Promise<RCANMessage>;
1905
+ declare function signMessage(msg: RCANMessage, keypair: MLDSAKeyPair): Promise<RCANMessage>;
1933
1906
  /**
1934
- * Verify the ML-DSA-65 signature (`pqSig`) on an RCAN message.
1907
+ * Verify the ML-DSA-65 signature on an RCANMessage.
1935
1908
  *
1936
- * @param msg Message with a `pqSig` field
1937
- * @param trustedKeys Trusted ML-DSA public key pairs
1938
- * @param requirePQ If true, raise when `pqSig` is absent (for post-2028 hard mode)
1909
+ * @throws {Error} if signature is missing, alg is not ml-dsa-65, key not found, or invalid.
1939
1910
  */
1940
- declare function verifyPQSignature(msg: RCANMessage, trustedKeys: MLDSAKeyPair[], requirePQ?: boolean): Promise<void>;
1911
+ declare function verifyMessage(msg: RCANMessage, trustedKeys: MLDSAKeyPair[]): Promise<void>;
1912
+ /** @deprecated Use signMessage() — Ed25519 is removed in RCAN v2.2 */
1913
+ declare const addPQSignature: typeof signMessage;
1914
+ /** @deprecated Use verifyMessage() — Ed25519 is removed in RCAN v2.2 */
1915
+ declare function verifyPQSignature(msg: RCANMessage, trustedKeys: MLDSAKeyPair[], _requirePQ?: boolean): Promise<void>;
1941
1916
 
1942
1917
  /**
1943
1918
  * rcan-ts — Official TypeScript SDK for RCAN v1.6
@@ -1951,4 +1926,4 @@ declare const VERSION = "0.6.0";
1951
1926
  /** @deprecated Use SPEC_VERSION from ./version instead */
1952
1927
  declare const RCAN_VERSION = "1.6";
1953
1928
 
1954
- export { AUTHORITY_ERROR_CODES, type ApprovalStatus, AuditChain, AuditError, type AuditExportRequest, type AuthorityAccessPayload, type AuthorityAccessPayloadWire, type AuthorityDataCategory, type AuthorityResponseData, type AuthorityResponsePayload, COMPETITION_SCOPE_LEVEL, CONTRIBUTE_SCOPE_LEVEL, type CachedKey, type ChainVerifyResult, ClockDriftError, type ClockSyncStatus, CommitmentRecord, type CommitmentRecordData, type CommitmentRecordJSON, type CompetitionBadge, type CompetitionEnter, type CompetitionFormat, type CompetitionScore, type ComputeResource, ConfidenceGate, type ConsentRequestParams, type ConsentResponseParams, type ConsentType, type ContributeCancel, type ContributeRequest, type ContributeResult, DEFAULT_LOA_POLICY, DataCategory, type DelegationHop, FIRMWARE_MANIFEST_PATH, FaultCode, type FaultReportParams, type FaultSeverity, type FederationSyncPayload, FederationSyncType, type FirmwareComponent, FirmwareIntegrityError, type FirmwareManifest, type FirmwareManifestWire, GateError, HiTLGate, type IdentityRecord, type JWKEntry, type JWKSDocument, KeyStore, LevelOfAssurance, type ListResult, type LoaPolicy, M2MAuthError, type M2MPeerClaims, type M2MTrustedClaims, M2M_TRUSTED_ISSUER, MLDSAKeyPair, type MLDSAKeyPairData, type MLDSASignatureBlock, type MediaChunk, MediaEncoding, MessageType, NodeClient, type OfflineCommandResult, OfflineModeManager, type OfflineState, PRODUCTION_LOA_POLICY, type PendingApproval, type PersonalResearchResult, QoSAckTimeoutError, QoSLevel, QoSManager, type QoSResult, type QoSSendOptions, RCANAddressError, type RCANAgentConfig, type RCANConfig, RCANConfigAuthorizationError, RCANDelegationChainError, RCANError, RCANGateError, RCANMessage, type RCANMessageData, type RCANMessageEnvelope, RCANMessageError, type RCANMetadata, RCANNodeError, RCANNodeNotFoundError, RCANNodeSyncError, RCANNodeTrustError, RCANRegistryError, type RCANRegistryNode, RCANReplayAttackError, type RCANResolveResult, RCANSignatureError, RCANValidationError, RCANVersionIncompatibleError, RCAN_VERSION, ROLE_JWT_LEVEL, RRF_REVOCATION_CACHE_TTL_MS, RRF_REVOCATION_URL, type RegistrationResult, RegistryClient, type RegistryIdentity, RegistryTier, ReplayCache, type ReplayCheckResult, type ReplayableMessage, type ResearchMetrics, RevocationCache$1 as RevocationCache, type RevocationStatus, type RevocationStatusValue, type Robot, type RobotRegistration, RobotURI, RobotURIError, type RobotURIOptions, Role, type RunType, SAFETY_MESSAGE_TYPE, SCOPE_MIN_ROLE, SDK_VERSION, SPEC_VERSION, type SafetyEvent, type SafetyMessage, type ScopeValidationResult, type SeasonStanding, type SenderType, type SignatureBlock, type StandingEntry, type StreamChunk, type TrainingConsentRequestParams, type TransparencyMessage, TransportEncoding, TransportError, TrustAnchorCache, VERSION, type ValidationResult, type WorkUnitStatus, addDelegationHop, addMediaInline, addMediaRef, addPQSignature, assertClockSynced, authorityAccessFromWire, authorityAccessToWire, canonicalManifestJson, checkClockSync, checkRevocation, decodeBleFrames, decodeCompact, decodeMinimal, encodeBleFrames, encodeCompact, encodeMinimal, extractIdentityFromJwt, extractLoaFromJwt, extractRoleFromJwt, fetchCanonicalSchema, fetchRRFRevocations, isAuthorityRequestValid, isM2mTrustedRevoked, isPreemptedBy, isSafetyMessage, makeCloudRelayMessage, makeCompetitionEnter, makeCompetitionScore, makeConfigUpdate, makeConsentDeny, makeConsentGrant, makeConsentRequest, makeContributeCancel, makeContributeRequest, makeContributeResult, makeEstopMessage, makeEstopWithQoS, makeFaultReport, makeFederationSync, makeKeyRotationMessage, makePersonalResearchResult, makeResumeMessage, makeRevocationBroadcast, makeSeasonStanding, makeStopMessage, makeStreamChunk, makeTrainingConsentDeny, makeTrainingConsentGrant, makeTrainingConsentRequest, makeTrainingDataMessage, makeTransparencyMessage, manifestFromWire, manifestToWire, parseM2mPeerToken, parseM2mTrustedToken, roleFromJwtLevel, selectTransport, validateAuthorityAccess, validateCompetitionScope, validateConfig, validateConfigAgainstSchema, validateConfigUpdate, validateConsentMessage, validateContributeScope, validateCrossRegistryCommand, validateDelegationChain, validateLoaForScope, validateManifest, validateMediaChunks, validateMessage, validateNodeAgainstSchema, validateReplay, validateRoleForScope, validateSafetyMessage, validateTrainingDataMessage, validateURI, validateVersionCompat, verifyM2mTrustedToken, verifyM2mTrustedTokenClaims, verifyPQSignature };
1929
+ export { AUTHORITY_ERROR_CODES, type ApprovalStatus, AuditChain, AuditError, type AuditExportRequest, type AuthorityAccessPayload, type AuthorityAccessPayloadWire, type AuthorityDataCategory, type AuthorityResponseData, type AuthorityResponsePayload, COMPETITION_SCOPE_LEVEL, CONTRIBUTE_SCOPE_LEVEL, type CachedKey, type ChainVerifyResult, ClockDriftError, type ClockSyncStatus, CommitmentRecord, type CommitmentRecordData, type CommitmentRecordJSON, type CompetitionBadge, type CompetitionEnter, type CompetitionFormat, type CompetitionScore, type ComputeResource, ConfidenceGate, type ConsentRequestParams, type ConsentResponseParams, type ConsentType, type ContributeCancel, type ContributeRequest, type ContributeResult, DEFAULT_LOA_POLICY, DataCategory, type DelegationHop, FIRMWARE_MANIFEST_PATH, FaultCode, type FaultReportParams, type FaultSeverity, type FederationSyncPayload, FederationSyncType, type FirmwareComponent, FirmwareIntegrityError, type FirmwareManifest, type FirmwareManifestWire, GateError, HiTLGate, type IdentityRecord, type JWKEntry, type JWKSDocument, KeyStore, LevelOfAssurance, type ListResult, type LoaPolicy, M2MAuthError, type M2MPeerClaims, type M2MTrustedClaims, M2M_TRUSTED_ISSUER, MLDSAKeyPair, type MLDSAKeyPairData, type MediaChunk, MediaEncoding, MessageType, NodeClient, type OfflineCommandResult, OfflineModeManager, type OfflineState, PRODUCTION_LOA_POLICY, type PendingApproval, type PersonalResearchResult, QoSAckTimeoutError, QoSLevel, QoSManager, type QoSResult, type QoSSendOptions, RCANAddressError, type RCANAgentConfig, type RCANConfig, RCANConfigAuthorizationError, RCANDelegationChainError, RCANError, RCANGateError, RCANMessage, type RCANMessageData, type RCANMessageEnvelope, RCANMessageError, type RCANMetadata, RCANNodeError, RCANNodeNotFoundError, RCANNodeSyncError, RCANNodeTrustError, RCANRegistryError, type RCANRegistryNode, RCANReplayAttackError, type RCANResolveResult, RCANSignatureError, RCANValidationError, RCANVersionIncompatibleError, RCAN_VERSION, ROLE_JWT_LEVEL, RRF_REVOCATION_CACHE_TTL_MS, RRF_REVOCATION_URL, type RegistrationResult, RegistryClient, type RegistryIdentity, RegistryTier, ReplayCache, type ReplayCheckResult, type ReplayableMessage, type ResearchMetrics, RevocationCache$1 as RevocationCache, type RevocationStatus, type RevocationStatusValue, type Robot, type RobotRegistration, RobotURI, RobotURIError, type RobotURIOptions, Role, type RunType, SAFETY_MESSAGE_TYPE, SCOPE_MIN_ROLE, SDK_VERSION, SPEC_VERSION, type SafetyEvent, type SafetyMessage, type ScopeValidationResult, type SeasonStanding, type SenderType, type SignatureBlock, type StandingEntry, type StreamChunk, type TrainingConsentRequestParams, type TransparencyMessage, TransportEncoding, TransportError, TrustAnchorCache, VERSION, type ValidationResult, type WorkUnitStatus, addDelegationHop, addMediaInline, addMediaRef, addPQSignature, assertClockSynced, authorityAccessFromWire, authorityAccessToWire, canonicalManifestJson, checkClockSync, checkRevocation, decodeBleFrames, decodeCompact, decodeMinimal, encodeBleFrames, encodeCompact, encodeMinimal, extractIdentityFromJwt, extractLoaFromJwt, extractRoleFromJwt, fetchCanonicalSchema, fetchRRFRevocations, isAuthorityRequestValid, isM2mTrustedRevoked, isPreemptedBy, isSafetyMessage, makeCloudRelayMessage, makeCompetitionEnter, makeCompetitionScore, makeConfigUpdate, makeConsentDeny, makeConsentGrant, makeConsentRequest, makeContributeCancel, makeContributeRequest, makeContributeResult, makeEstopMessage, makeEstopWithQoS, makeFaultReport, makeFederationSync, makeKeyRotationMessage, makePersonalResearchResult, makeResumeMessage, makeRevocationBroadcast, makeSeasonStanding, makeStopMessage, makeStreamChunk, makeTrainingConsentDeny, makeTrainingConsentGrant, makeTrainingConsentRequest, makeTrainingDataMessage, makeTransparencyMessage, manifestFromWire, manifestToWire, parseM2mPeerToken, parseM2mTrustedToken, roleFromJwtLevel, selectTransport, signMessage, validateAuthorityAccess, validateCompetitionScope, validateConfig, validateConfigAgainstSchema, validateConfigUpdate, validateConsentMessage, validateContributeScope, validateCrossRegistryCommand, validateDelegationChain, validateLoaForScope, validateManifest, validateMediaChunks, validateMessage, validateNodeAgainstSchema, validateReplay, validateRoleForScope, validateSafetyMessage, validateTrainingDataMessage, validateURI, validateVersionCompat, verifyM2mTrustedToken, verifyM2mTrustedTokenClaims, verifyMessage, verifyPQSignature };
package/dist/index.d.ts CHANGED
@@ -109,8 +109,9 @@ interface DelegationHop {
109
109
  scope: string;
110
110
  signature: string;
111
111
  }
112
+ /** RCAN v2.2: ML-DSA-65 is the only valid alg ("ml-dsa-65"). Ed25519 is deprecated. */
112
113
  interface SignatureBlock {
113
- alg: string;
114
+ alg: "ml-dsa-65";
114
115
  kid: string;
115
116
  sig: string;
116
117
  }
@@ -767,7 +768,7 @@ declare function makeTransparencyMessage(ruri: string, disclosure: string, deleg
767
768
  /** The RCAN spec version this SDK implements. */
768
769
  declare const SPEC_VERSION = "2.2.0";
769
770
  /** The SDK release version. */
770
- declare const SDK_VERSION = "1.2.0";
771
+ declare const SDK_VERSION = "1.2.1";
771
772
  /**
772
773
  * Validate version compatibility.
773
774
  *
@@ -1863,81 +1864,55 @@ declare function verifyM2mTrustedToken(token: string, targetRrn: string, options
1863
1864
  }): Promise<M2MTrustedClaims>;
1864
1865
 
1865
1866
  /**
1866
- * RCAN v2.2 Post-Quantum Hybrid Signing — ML-DSA-65 (NIST FIPS 204)
1867
- *
1868
- * Provides MLDSAKeyPair for post-quantum signing alongside the existing
1869
- * Ed25519 SignatureBlock. In hybrid mode a message carries both:
1870
- * - `signature` — Ed25519 SignatureBlock (backward-compat with v2.1)
1871
- * - `pqSig` — MLDSASignatureBlock (new in v2.2)
1867
+ * RCAN v2.2 ML-DSA-65 Signing (NIST FIPS 204)
1872
1868
  *
1873
- * Key sizes (ML-DSA-65, NIST security level 3):
1874
- * Public key: 1952 bytes
1875
- * Private key: 4032 bytes
1876
- * Signature: 3309 bytes
1869
+ * Ed25519 is deprecated. ML-DSA-65 is the ONLY signing algorithm.
1870
+ * All signed messages carry a ``signature`` block with ``alg: "ml-dsa-65"``.
1877
1871
  *
1878
1872
  * Requires: @noble/post-quantum (npm install @noble/post-quantum)
1879
1873
  *
1880
- * Spec: https://rcan.dev/spec#section-7-2
1874
+ * Spec: https://rcan.dev/spec/v2.2#section-7-2
1881
1875
  */
1882
1876
 
1883
- /** @deprecated use PQSignatureBlock */
1884
- type MLDSASignatureBlock = PQSignatureBlock;
1885
1877
  interface MLDSAKeyPairData {
1886
- /** Public key bytes (1952 bytes) */
1887
1878
  publicKey: Uint8Array;
1888
- /** Private key bytes (4032 bytes). Absent for verify-only key pairs. */
1889
1879
  secretKey?: Uint8Array;
1890
- /** 8-char hex key ID */
1891
1880
  keyId: string;
1892
1881
  }
1893
1882
  /**
1894
1883
  * An ML-DSA-65 (CRYSTALS-Dilithium, NIST FIPS 204) key pair.
1895
1884
  *
1896
- * Immutable value object. Build via {@link MLDSAKeyPair.generate} or
1897
- * {@link MLDSAKeyPair.fromPublicKey}.
1885
+ * This is the ONLY signing key type in RCAN v2.2+. Ed25519 is deprecated.
1898
1886
  */
1899
1887
  declare class MLDSAKeyPair {
1900
1888
  readonly keyId: string;
1901
1889
  readonly publicKey: Uint8Array;
1902
1890
  readonly secretKey: Uint8Array | undefined;
1903
1891
  private constructor();
1904
- /** Generate a new ML-DSA-65 key pair. */
1905
1892
  static generate(): Promise<MLDSAKeyPair>;
1906
- /** Build a verify-only key pair from raw public key bytes. */
1907
1893
  static fromPublicKey(publicKey: Uint8Array): Promise<MLDSAKeyPair>;
1908
- /** Build a full key pair from saved bytes (public + secret). */
1909
1894
  static fromKeyMaterial(publicKey: Uint8Array, secretKey: Uint8Array): Promise<MLDSAKeyPair>;
1910
1895
  get hasPrivateKey(): boolean;
1911
- /** Sign raw bytes; returns ML-DSA-65 signature (3309 bytes). */
1912
1896
  signBytes(data: Uint8Array): Promise<Uint8Array>;
1913
- /**
1914
- * Verify an ML-DSA-65 signature.
1915
- * @returns true if valid
1916
- * @throws {Error} on invalid signature
1917
- */
1918
1897
  verifyBytes(data: Uint8Array, signature: Uint8Array): Promise<void>;
1919
1898
  toString(): string;
1920
1899
  }
1921
1900
  /**
1922
- * Add an ML-DSA-65 signature (`pqSig`) to an RCAN message.
1923
- *
1924
- * This is the v2.2 hybrid complement to the existing Ed25519 signature.
1925
- * Call {@link signMessageEd25519} (or the existing signing path) first to set
1926
- * `signature`, then call this to append `pqSig`.
1901
+ * Sign an RCANMessage with ML-DSA-65 (the only signing algorithm in RCAN v2.2).
1927
1902
  *
1928
- * @param msg RCAN message (mutated in place sets `pqSig`)
1929
- * @param keypair ML-DSA-65 key pair with private key
1930
- * @returns The same message cast to include `pqSig`
1903
+ * Sets msg.signature = { alg: "ml-dsa-65", kid, sig }.
1931
1904
  */
1932
- declare function addPQSignature(msg: RCANMessage, keypair: MLDSAKeyPair): Promise<RCANMessage>;
1905
+ declare function signMessage(msg: RCANMessage, keypair: MLDSAKeyPair): Promise<RCANMessage>;
1933
1906
  /**
1934
- * Verify the ML-DSA-65 signature (`pqSig`) on an RCAN message.
1907
+ * Verify the ML-DSA-65 signature on an RCANMessage.
1935
1908
  *
1936
- * @param msg Message with a `pqSig` field
1937
- * @param trustedKeys Trusted ML-DSA public key pairs
1938
- * @param requirePQ If true, raise when `pqSig` is absent (for post-2028 hard mode)
1909
+ * @throws {Error} if signature is missing, alg is not ml-dsa-65, key not found, or invalid.
1939
1910
  */
1940
- declare function verifyPQSignature(msg: RCANMessage, trustedKeys: MLDSAKeyPair[], requirePQ?: boolean): Promise<void>;
1911
+ declare function verifyMessage(msg: RCANMessage, trustedKeys: MLDSAKeyPair[]): Promise<void>;
1912
+ /** @deprecated Use signMessage() — Ed25519 is removed in RCAN v2.2 */
1913
+ declare const addPQSignature: typeof signMessage;
1914
+ /** @deprecated Use verifyMessage() — Ed25519 is removed in RCAN v2.2 */
1915
+ declare function verifyPQSignature(msg: RCANMessage, trustedKeys: MLDSAKeyPair[], _requirePQ?: boolean): Promise<void>;
1941
1916
 
1942
1917
  /**
1943
1918
  * rcan-ts — Official TypeScript SDK for RCAN v1.6
@@ -1951,4 +1926,4 @@ declare const VERSION = "0.6.0";
1951
1926
  /** @deprecated Use SPEC_VERSION from ./version instead */
1952
1927
  declare const RCAN_VERSION = "1.6";
1953
1928
 
1954
- export { AUTHORITY_ERROR_CODES, type ApprovalStatus, AuditChain, AuditError, type AuditExportRequest, type AuthorityAccessPayload, type AuthorityAccessPayloadWire, type AuthorityDataCategory, type AuthorityResponseData, type AuthorityResponsePayload, COMPETITION_SCOPE_LEVEL, CONTRIBUTE_SCOPE_LEVEL, type CachedKey, type ChainVerifyResult, ClockDriftError, type ClockSyncStatus, CommitmentRecord, type CommitmentRecordData, type CommitmentRecordJSON, type CompetitionBadge, type CompetitionEnter, type CompetitionFormat, type CompetitionScore, type ComputeResource, ConfidenceGate, type ConsentRequestParams, type ConsentResponseParams, type ConsentType, type ContributeCancel, type ContributeRequest, type ContributeResult, DEFAULT_LOA_POLICY, DataCategory, type DelegationHop, FIRMWARE_MANIFEST_PATH, FaultCode, type FaultReportParams, type FaultSeverity, type FederationSyncPayload, FederationSyncType, type FirmwareComponent, FirmwareIntegrityError, type FirmwareManifest, type FirmwareManifestWire, GateError, HiTLGate, type IdentityRecord, type JWKEntry, type JWKSDocument, KeyStore, LevelOfAssurance, type ListResult, type LoaPolicy, M2MAuthError, type M2MPeerClaims, type M2MTrustedClaims, M2M_TRUSTED_ISSUER, MLDSAKeyPair, type MLDSAKeyPairData, type MLDSASignatureBlock, type MediaChunk, MediaEncoding, MessageType, NodeClient, type OfflineCommandResult, OfflineModeManager, type OfflineState, PRODUCTION_LOA_POLICY, type PendingApproval, type PersonalResearchResult, QoSAckTimeoutError, QoSLevel, QoSManager, type QoSResult, type QoSSendOptions, RCANAddressError, type RCANAgentConfig, type RCANConfig, RCANConfigAuthorizationError, RCANDelegationChainError, RCANError, RCANGateError, RCANMessage, type RCANMessageData, type RCANMessageEnvelope, RCANMessageError, type RCANMetadata, RCANNodeError, RCANNodeNotFoundError, RCANNodeSyncError, RCANNodeTrustError, RCANRegistryError, type RCANRegistryNode, RCANReplayAttackError, type RCANResolveResult, RCANSignatureError, RCANValidationError, RCANVersionIncompatibleError, RCAN_VERSION, ROLE_JWT_LEVEL, RRF_REVOCATION_CACHE_TTL_MS, RRF_REVOCATION_URL, type RegistrationResult, RegistryClient, type RegistryIdentity, RegistryTier, ReplayCache, type ReplayCheckResult, type ReplayableMessage, type ResearchMetrics, RevocationCache$1 as RevocationCache, type RevocationStatus, type RevocationStatusValue, type Robot, type RobotRegistration, RobotURI, RobotURIError, type RobotURIOptions, Role, type RunType, SAFETY_MESSAGE_TYPE, SCOPE_MIN_ROLE, SDK_VERSION, SPEC_VERSION, type SafetyEvent, type SafetyMessage, type ScopeValidationResult, type SeasonStanding, type SenderType, type SignatureBlock, type StandingEntry, type StreamChunk, type TrainingConsentRequestParams, type TransparencyMessage, TransportEncoding, TransportError, TrustAnchorCache, VERSION, type ValidationResult, type WorkUnitStatus, addDelegationHop, addMediaInline, addMediaRef, addPQSignature, assertClockSynced, authorityAccessFromWire, authorityAccessToWire, canonicalManifestJson, checkClockSync, checkRevocation, decodeBleFrames, decodeCompact, decodeMinimal, encodeBleFrames, encodeCompact, encodeMinimal, extractIdentityFromJwt, extractLoaFromJwt, extractRoleFromJwt, fetchCanonicalSchema, fetchRRFRevocations, isAuthorityRequestValid, isM2mTrustedRevoked, isPreemptedBy, isSafetyMessage, makeCloudRelayMessage, makeCompetitionEnter, makeCompetitionScore, makeConfigUpdate, makeConsentDeny, makeConsentGrant, makeConsentRequest, makeContributeCancel, makeContributeRequest, makeContributeResult, makeEstopMessage, makeEstopWithQoS, makeFaultReport, makeFederationSync, makeKeyRotationMessage, makePersonalResearchResult, makeResumeMessage, makeRevocationBroadcast, makeSeasonStanding, makeStopMessage, makeStreamChunk, makeTrainingConsentDeny, makeTrainingConsentGrant, makeTrainingConsentRequest, makeTrainingDataMessage, makeTransparencyMessage, manifestFromWire, manifestToWire, parseM2mPeerToken, parseM2mTrustedToken, roleFromJwtLevel, selectTransport, validateAuthorityAccess, validateCompetitionScope, validateConfig, validateConfigAgainstSchema, validateConfigUpdate, validateConsentMessage, validateContributeScope, validateCrossRegistryCommand, validateDelegationChain, validateLoaForScope, validateManifest, validateMediaChunks, validateMessage, validateNodeAgainstSchema, validateReplay, validateRoleForScope, validateSafetyMessage, validateTrainingDataMessage, validateURI, validateVersionCompat, verifyM2mTrustedToken, verifyM2mTrustedTokenClaims, verifyPQSignature };
1929
+ export { AUTHORITY_ERROR_CODES, type ApprovalStatus, AuditChain, AuditError, type AuditExportRequest, type AuthorityAccessPayload, type AuthorityAccessPayloadWire, type AuthorityDataCategory, type AuthorityResponseData, type AuthorityResponsePayload, COMPETITION_SCOPE_LEVEL, CONTRIBUTE_SCOPE_LEVEL, type CachedKey, type ChainVerifyResult, ClockDriftError, type ClockSyncStatus, CommitmentRecord, type CommitmentRecordData, type CommitmentRecordJSON, type CompetitionBadge, type CompetitionEnter, type CompetitionFormat, type CompetitionScore, type ComputeResource, ConfidenceGate, type ConsentRequestParams, type ConsentResponseParams, type ConsentType, type ContributeCancel, type ContributeRequest, type ContributeResult, DEFAULT_LOA_POLICY, DataCategory, type DelegationHop, FIRMWARE_MANIFEST_PATH, FaultCode, type FaultReportParams, type FaultSeverity, type FederationSyncPayload, FederationSyncType, type FirmwareComponent, FirmwareIntegrityError, type FirmwareManifest, type FirmwareManifestWire, GateError, HiTLGate, type IdentityRecord, type JWKEntry, type JWKSDocument, KeyStore, LevelOfAssurance, type ListResult, type LoaPolicy, M2MAuthError, type M2MPeerClaims, type M2MTrustedClaims, M2M_TRUSTED_ISSUER, MLDSAKeyPair, type MLDSAKeyPairData, type MediaChunk, MediaEncoding, MessageType, NodeClient, type OfflineCommandResult, OfflineModeManager, type OfflineState, PRODUCTION_LOA_POLICY, type PendingApproval, type PersonalResearchResult, QoSAckTimeoutError, QoSLevel, QoSManager, type QoSResult, type QoSSendOptions, RCANAddressError, type RCANAgentConfig, type RCANConfig, RCANConfigAuthorizationError, RCANDelegationChainError, RCANError, RCANGateError, RCANMessage, type RCANMessageData, type RCANMessageEnvelope, RCANMessageError, type RCANMetadata, RCANNodeError, RCANNodeNotFoundError, RCANNodeSyncError, RCANNodeTrustError, RCANRegistryError, type RCANRegistryNode, RCANReplayAttackError, type RCANResolveResult, RCANSignatureError, RCANValidationError, RCANVersionIncompatibleError, RCAN_VERSION, ROLE_JWT_LEVEL, RRF_REVOCATION_CACHE_TTL_MS, RRF_REVOCATION_URL, type RegistrationResult, RegistryClient, type RegistryIdentity, RegistryTier, ReplayCache, type ReplayCheckResult, type ReplayableMessage, type ResearchMetrics, RevocationCache$1 as RevocationCache, type RevocationStatus, type RevocationStatusValue, type Robot, type RobotRegistration, RobotURI, RobotURIError, type RobotURIOptions, Role, type RunType, SAFETY_MESSAGE_TYPE, SCOPE_MIN_ROLE, SDK_VERSION, SPEC_VERSION, type SafetyEvent, type SafetyMessage, type ScopeValidationResult, type SeasonStanding, type SenderType, type SignatureBlock, type StandingEntry, type StreamChunk, type TrainingConsentRequestParams, type TransparencyMessage, TransportEncoding, TransportError, TrustAnchorCache, VERSION, type ValidationResult, type WorkUnitStatus, addDelegationHop, addMediaInline, addMediaRef, addPQSignature, assertClockSynced, authorityAccessFromWire, authorityAccessToWire, canonicalManifestJson, checkClockSync, checkRevocation, decodeBleFrames, decodeCompact, decodeMinimal, encodeBleFrames, encodeCompact, encodeMinimal, extractIdentityFromJwt, extractLoaFromJwt, extractRoleFromJwt, fetchCanonicalSchema, fetchRRFRevocations, isAuthorityRequestValid, isM2mTrustedRevoked, isPreemptedBy, isSafetyMessage, makeCloudRelayMessage, makeCompetitionEnter, makeCompetitionScore, makeConfigUpdate, makeConsentDeny, makeConsentGrant, makeConsentRequest, makeContributeCancel, makeContributeRequest, makeContributeResult, makeEstopMessage, makeEstopWithQoS, makeFaultReport, makeFederationSync, makeKeyRotationMessage, makePersonalResearchResult, makeResumeMessage, makeRevocationBroadcast, makeSeasonStanding, makeStopMessage, makeStreamChunk, makeTrainingConsentDeny, makeTrainingConsentGrant, makeTrainingConsentRequest, makeTrainingDataMessage, makeTransparencyMessage, manifestFromWire, manifestToWire, parseM2mPeerToken, parseM2mTrustedToken, roleFromJwtLevel, selectTransport, signMessage, validateAuthorityAccess, validateCompetitionScope, validateConfig, validateConfigAgainstSchema, validateConfigUpdate, validateConsentMessage, validateContributeScope, validateCrossRegistryCommand, validateDelegationChain, validateLoaForScope, validateManifest, validateMediaChunks, validateMessage, validateNodeAgainstSchema, validateReplay, validateRoleForScope, validateSafetyMessage, validateTrainingDataMessage, validateURI, validateVersionCompat, verifyM2mTrustedToken, verifyM2mTrustedTokenClaims, verifyMessage, verifyPQSignature };
package/dist/index.js CHANGED
@@ -151,6 +151,7 @@ __export(index_exports, {
151
151
  parseM2mTrustedToken: () => parseM2mTrustedToken,
152
152
  roleFromJwtLevel: () => roleFromJwtLevel,
153
153
  selectTransport: () => selectTransport,
154
+ signMessage: () => signMessage,
154
155
  validateAuthorityAccess: () => validateAuthorityAccess,
155
156
  validateCompetitionScope: () => validateCompetitionScope,
156
157
  validateConfig: () => validateConfig,
@@ -173,6 +174,7 @@ __export(index_exports, {
173
174
  validateVersionCompat: () => validateVersionCompat,
174
175
  verifyM2mTrustedToken: () => verifyM2mTrustedToken,
175
176
  verifyM2mTrustedTokenClaims: () => verifyM2mTrustedTokenClaims,
177
+ verifyMessage: () => verifyMessage,
176
178
  verifyPQSignature: () => verifyPQSignature
177
179
  });
178
180
  module.exports = __toCommonJS(index_exports);
@@ -269,7 +271,7 @@ var RobotURI = class _RobotURI {
269
271
 
270
272
  // src/version.ts
271
273
  var SPEC_VERSION = "2.2.0";
272
- var SDK_VERSION = "1.2.0";
274
+ var SDK_VERSION = "1.2.1";
273
275
  function validateVersionCompat(incomingVersion, localVersion = SPEC_VERSION) {
274
276
  const parseParts = (v) => {
275
277
  const parts = v.split(".");
@@ -448,7 +450,6 @@ var RCANMessage = class _RCANMessage {
448
450
  if (this.mediaChunks !== void 0) obj.mediaChunks = this.mediaChunks;
449
451
  if (this.firmwareHash !== void 0) obj.firmwareHash = this.firmwareHash;
450
452
  if (this.attestationRef !== void 0) obj.attestationRef = this.attestationRef;
451
- if (this.pqSig !== void 0) obj.pqSig = this.pqSig;
452
453
  return obj;
453
454
  }
454
455
  /** Serialize to JSON string */
@@ -3275,21 +3276,15 @@ function fromBase64url(b64) {
3275
3276
  return bytes;
3276
3277
  }
3277
3278
  async function sha256hex(data) {
3278
- const g = typeof globalThis !== "undefined" ? globalThis : {};
3279
- const webcrypto = g.crypto;
3280
- const subtle = webcrypto?.subtle;
3281
- if (subtle) {
3282
- const buf = await subtle.digest("SHA-256", data);
3279
+ if (typeof crypto !== "undefined" && crypto.subtle) {
3280
+ const buf = await crypto.subtle.digest("SHA-256", data.buffer);
3283
3281
  return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 8);
3284
3282
  }
3285
- const nodeCrypto = await import("crypto").catch(() => null);
3286
- if (nodeCrypto) {
3287
- return nodeCrypto.createHash("sha256").update(data).digest("hex").slice(0, 8);
3288
- }
3289
- throw new Error("No SHA-256 implementation available");
3283
+ const { createHash } = require("crypto");
3284
+ return createHash("sha256").update(data).digest("hex").slice(0, 8);
3290
3285
  }
3291
3286
  var _mlDsaModule;
3292
- async function requireNoblePostQuantum() {
3287
+ async function requireMlDsa() {
3293
3288
  if (_mlDsaModule) return _mlDsaModule;
3294
3289
  if (typeof require !== "undefined") {
3295
3290
  try {
@@ -3303,7 +3298,7 @@ async function requireNoblePostQuantum() {
3303
3298
  return _mlDsaModule;
3304
3299
  } catch {
3305
3300
  throw new Error(
3306
- "ML-DSA signing requires @noble/post-quantum. Install with: npm install @noble/post-quantum"
3301
+ "ML-DSA-65 signing requires @noble/post-quantum. Install with: npm install @noble/post-quantum"
3307
3302
  );
3308
3303
  }
3309
3304
  }
@@ -3316,23 +3311,16 @@ var MLDSAKeyPair = class _MLDSAKeyPair {
3316
3311
  this.publicKey = data.publicKey;
3317
3312
  this.secretKey = data.secretKey;
3318
3313
  }
3319
- /** Generate a new ML-DSA-65 key pair. */
3320
3314
  static async generate() {
3321
- const { ml_dsa65 } = await requireNoblePostQuantum();
3322
- const kp = ml_dsa65.keygen();
3315
+ const m = await requireMlDsa();
3316
+ const kp = m.ml_dsa65.keygen();
3323
3317
  const keyId = await sha256hex(kp.publicKey);
3324
- return new _MLDSAKeyPair({
3325
- publicKey: kp.publicKey,
3326
- secretKey: kp.secretKey,
3327
- keyId
3328
- });
3318
+ return new _MLDSAKeyPair({ publicKey: kp.publicKey, secretKey: kp.secretKey, keyId });
3329
3319
  }
3330
- /** Build a verify-only key pair from raw public key bytes. */
3331
3320
  static async fromPublicKey(publicKey) {
3332
3321
  const keyId = await sha256hex(publicKey);
3333
3322
  return new _MLDSAKeyPair({ publicKey, keyId });
3334
3323
  }
3335
- /** Build a full key pair from saved bytes (public + secret). */
3336
3324
  static async fromKeyMaterial(publicKey, secretKey) {
3337
3325
  const keyId = await sha256hex(publicKey);
3338
3326
  return new _MLDSAKeyPair({ publicKey, secretKey, keyId });
@@ -3340,82 +3328,68 @@ var MLDSAKeyPair = class _MLDSAKeyPair {
3340
3328
  get hasPrivateKey() {
3341
3329
  return this.secretKey !== void 0;
3342
3330
  }
3343
- /** Sign raw bytes; returns ML-DSA-65 signature (3309 bytes). */
3344
3331
  async signBytes(data) {
3345
- if (!this.secretKey) {
3346
- throw new Error("Cannot sign: MLDSAKeyPair has no private key (verify-only)");
3347
- }
3348
- const { ml_dsa65 } = await requireNoblePostQuantum();
3349
- return ml_dsa65.sign(data, this.secretKey);
3332
+ if (!this.secretKey) throw new Error("Cannot sign: MLDSAKeyPair has no private key (verify-only)");
3333
+ const m = await requireMlDsa();
3334
+ return m.ml_dsa65.sign(data, this.secretKey);
3350
3335
  }
3351
- /**
3352
- * Verify an ML-DSA-65 signature.
3353
- * @returns true if valid
3354
- * @throws {Error} on invalid signature
3355
- */
3356
3336
  async verifyBytes(data, signature) {
3357
- const { ml_dsa65 } = await requireNoblePostQuantum();
3358
- const ok = ml_dsa65.verify(signature, data, this.publicKey);
3359
- if (!ok) throw new Error("ML-DSA signature verification failed");
3337
+ const m = await requireMlDsa();
3338
+ const ok = m.ml_dsa65.verify(signature, data, this.publicKey);
3339
+ if (!ok) throw new Error("ML-DSA-65 signature verification failed");
3360
3340
  }
3361
3341
  toString() {
3362
- const mode = this.hasPrivateKey ? "private+public" : "public-only";
3363
- return `MLDSAKeyPair(keyId=${this.keyId}, alg=ML-DSA-65, ${mode})`;
3342
+ return `MLDSAKeyPair(keyId=${this.keyId}, alg=ML-DSA-65, ${this.hasPrivateKey ? "private+public" : "public-only"})`;
3364
3343
  }
3365
3344
  };
3366
3345
  function canonicalMessageBytes(msg) {
3367
- const m = msg;
3368
3346
  const payload = {
3369
3347
  rcan: msg.rcan,
3370
- msg_id: m["msgId"] ?? m["msg_id"] ?? "",
3348
+ msg_id: msg["msgId"] ?? "",
3371
3349
  timestamp: msg.timestamp,
3372
3350
  cmd: msg.cmd,
3373
3351
  target: msg.target,
3374
3352
  params: msg.params
3375
3353
  };
3376
- const sorted = JSON.stringify(
3377
- Object.fromEntries(Object.entries(payload).sort()),
3378
- null,
3379
- void 0
3354
+ return new TextEncoder().encode(
3355
+ JSON.stringify(Object.fromEntries(Object.entries(payload).sort()))
3380
3356
  );
3381
- return new TextEncoder().encode(sorted);
3382
3357
  }
3383
- async function addPQSignature(msg, keypair) {
3358
+ async function signMessage(msg, keypair) {
3384
3359
  const payload = canonicalMessageBytes(msg);
3385
3360
  const rawSig = await keypair.signBytes(payload);
3386
- const block = {
3361
+ msg["signature"] = {
3387
3362
  alg: "ml-dsa-65",
3388
3363
  kid: keypair.keyId,
3389
3364
  sig: toBase64url(rawSig)
3390
3365
  };
3391
- msg["pqSig"] = block;
3392
3366
  return msg;
3393
3367
  }
3394
- async function verifyPQSignature(msg, trustedKeys, requirePQ = false) {
3395
- const pqSig = msg["pqSig"];
3396
- if (!pqSig) {
3397
- if (requirePQ) {
3398
- throw new Error("ML-DSA signature (pqSig) required but missing from message");
3399
- }
3400
- return;
3401
- }
3402
- if (pqSig.alg !== "ml-dsa-65") {
3403
- throw new Error(`Unsupported PQ signature algorithm: ${pqSig.alg}`);
3368
+ async function verifyMessage(msg, trustedKeys) {
3369
+ const sig = msg.signature;
3370
+ if (!sig) throw new Error("Message is unsigned \u2014 signature field missing");
3371
+ if (sig.alg !== "ml-dsa-65") {
3372
+ throw new Error(
3373
+ `Unsupported signature algorithm: ${sig.alg}. RCAN v2.2 requires ml-dsa-65 (Ed25519 is deprecated).`
3374
+ );
3404
3375
  }
3405
- const matched = trustedKeys.find((k) => k.keyId === pqSig.kid);
3376
+ const matched = trustedKeys.find((k) => k.keyId === sig.kid);
3406
3377
  if (!matched) {
3407
3378
  throw new Error(
3408
- `No trusted ML-DSA key with kid=${pqSig.kid}. Known kids: [${trustedKeys.map((k) => k.keyId).join(", ")}]`
3379
+ `No trusted ML-DSA-65 key with kid=${sig.kid}. Known kids: [${trustedKeys.map((k) => k.keyId).join(", ")}]`
3409
3380
  );
3410
3381
  }
3411
3382
  let rawSig;
3412
3383
  try {
3413
- rawSig = fromBase64url(pqSig.sig);
3384
+ rawSig = fromBase64url(sig.sig);
3414
3385
  } catch (e) {
3415
- throw new Error(`Invalid base64url ML-DSA signature: ${e}`);
3386
+ throw new Error(`Invalid base64url sig: ${e}`);
3416
3387
  }
3417
- const payload = canonicalMessageBytes(msg);
3418
- await matched.verifyBytes(payload, rawSig);
3388
+ await matched.verifyBytes(canonicalMessageBytes(msg), rawSig);
3389
+ }
3390
+ var addPQSignature = signMessage;
3391
+ async function verifyPQSignature(msg, trustedKeys, _requirePQ = true) {
3392
+ return verifyMessage(msg, trustedKeys);
3419
3393
  }
3420
3394
 
3421
3395
  // src/index.ts
@@ -3544,6 +3518,7 @@ var RCAN_VERSION = "1.6";
3544
3518
  parseM2mTrustedToken,
3545
3519
  roleFromJwtLevel,
3546
3520
  selectTransport,
3521
+ signMessage,
3547
3522
  validateAuthorityAccess,
3548
3523
  validateCompetitionScope,
3549
3524
  validateConfig,
@@ -3566,6 +3541,7 @@ var RCAN_VERSION = "1.6";
3566
3541
  validateVersionCompat,
3567
3542
  verifyM2mTrustedToken,
3568
3543
  verifyM2mTrustedTokenClaims,
3544
+ verifyMessage,
3569
3545
  verifyPQSignature
3570
3546
  });
3571
3547
  //# sourceMappingURL=index.js.map