@twin.org/crypto 0.0.1 → 0.0.2-next.4

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.
@@ -8,6 +8,7 @@ var blake2b = require('@noble/hashes/blake2b');
8
8
  var bip32 = require('@scure/bip32');
9
9
  var slip10_js = require('micro-key-producer/slip10.js');
10
10
  var chacha = require('@noble/ciphers/chacha');
11
+ var node_crypto = require('node:crypto');
11
12
  var blake3 = require('@noble/hashes/blake3');
12
13
  var hmac = require('@noble/hashes/hmac');
13
14
  var sha1 = require('@noble/hashes/sha1');
@@ -717,8 +718,292 @@ class ChaCha20Poly1305 {
717
718
  // Copyright 2024 IOTA Stiftung.
718
719
  // SPDX-License-Identifier: Apache-2.0.
719
720
  /**
720
- * This is a TypeScript port of https://github.com/katzenpost/core/blob/master/crypto/extra25519/extra25519.go.
721
+ * Implementation of the RSA cipher.
721
722
  */
723
+ class RSA {
724
+ /**
725
+ * Runtime name for the class.
726
+ * @internal
727
+ */
728
+ static _CLASS_NAME = "RSA";
729
+ /**
730
+ * The public key for encryption.
731
+ * @internal
732
+ */
733
+ _publicKeyBytes;
734
+ /**
735
+ * The private key for decryption.
736
+ * @internal
737
+ */
738
+ _privateKeyBytes;
739
+ /**
740
+ * The public key for encryption.
741
+ * @internal
742
+ */
743
+ _publicKey;
744
+ /**
745
+ * The private key for decryption.
746
+ * @internal
747
+ */
748
+ _privateKey;
749
+ /**
750
+ * The block size for encryption.
751
+ * @internal
752
+ */
753
+ _blockSize;
754
+ /**
755
+ * The key size for decryption.
756
+ * @internal
757
+ */
758
+ _keySize;
759
+ /**
760
+ * Create a new instance of RSA.
761
+ * @param publicKey The public key for encryption (DER format as Uint8Array).
762
+ * @param privateKey The private key for decryption (DER format as Uint8Array).
763
+ */
764
+ constructor(publicKey, privateKey) {
765
+ core.Guards.uint8Array(RSA._CLASS_NAME, "publicKey", publicKey);
766
+ this._publicKeyBytes = publicKey;
767
+ this._privateKeyBytes = privateKey;
768
+ }
769
+ /**
770
+ * Generate a new RSA key pair in PKCS8 format.
771
+ * @param modulusLength The key size in bits (default: 2048).
772
+ * @returns The public and private keys as Uint8Array.
773
+ */
774
+ static async generateKeyPair(modulusLength = 2048) {
775
+ const { publicKey, privateKey } = node_crypto.generateKeyPairSync("rsa", {
776
+ modulusLength,
777
+ publicKeyEncoding: {
778
+ type: "spki",
779
+ format: "der"
780
+ },
781
+ privateKeyEncoding: {
782
+ type: "pkcs8",
783
+ format: "der"
784
+ }
785
+ });
786
+ return {
787
+ publicKey: new Uint8Array(publicKey),
788
+ privateKey: new Uint8Array(privateKey)
789
+ };
790
+ }
791
+ /**
792
+ * Convert a PKCS1 key to a PKCS8 key.
793
+ * @param pkcs1Key The PKCS1 key as Uint8Array.
794
+ * @returns The PKCS8 key as Uint8Array.
795
+ */
796
+ static async convertPkcs1ToPkcs8(pkcs1Key) {
797
+ core.Guards.uint8Array(RSA._CLASS_NAME, "pkcs1Key", pkcs1Key);
798
+ const privateKey = node_crypto.createPrivateKey({
799
+ key: Buffer.from(pkcs1Key),
800
+ format: "der",
801
+ type: "pkcs1"
802
+ });
803
+ return new Uint8Array(privateKey.export({
804
+ format: "der",
805
+ type: "pkcs8"
806
+ }));
807
+ }
808
+ /**
809
+ * Break the private key down in to its components.
810
+ * @param pkcs8Key The PKCS8 key as Uint8Array.
811
+ * @returns The key components.
812
+ */
813
+ static async getPrivateKeyComponents(pkcs8Key) {
814
+ core.Guards.uint8Array(RSA._CLASS_NAME, "pkcs8Key", pkcs8Key);
815
+ const privateKey = node_crypto.createPrivateKey({
816
+ key: Buffer.from(pkcs8Key),
817
+ format: "der",
818
+ type: "pkcs8"
819
+ });
820
+ const jwk = privateKey.export({ format: "jwk" });
821
+ return {
822
+ n: this.base64UrlToBigInt(jwk.n),
823
+ e: this.base64UrlToBigInt(jwk.e),
824
+ d: this.base64UrlToBigInt(jwk.d),
825
+ p: this.base64UrlToBigInt(jwk.p),
826
+ q: this.base64UrlToBigInt(jwk.q),
827
+ dp: this.base64UrlToBigInt(jwk.dp),
828
+ dq: this.base64UrlToBigInt(jwk.dq),
829
+ qi: this.base64UrlToBigInt(jwk.qi)
830
+ };
831
+ }
832
+ /**
833
+ * Break the public key down in to its components.
834
+ * @param spkiKey The SPKI key as Uint8Array.
835
+ * @returns The key components.
836
+ */
837
+ static async getPublicKeyComponents(spkiKey) {
838
+ core.Guards.uint8Array(RSA._CLASS_NAME, "spkiKey", spkiKey);
839
+ const publicKey = node_crypto.createPublicKey({
840
+ key: Buffer.from(spkiKey),
841
+ format: "der",
842
+ type: "spki"
843
+ });
844
+ const jwk = publicKey.export({ format: "jwk" });
845
+ return {
846
+ n: this.base64UrlToBigInt(jwk.n),
847
+ e: this.base64UrlToBigInt(jwk.e)
848
+ };
849
+ }
850
+ /**
851
+ * Convert base64 encoded data to a big int.
852
+ * @param bytes The bytes to convert.
853
+ * @returns The bigint representation of the bytes.
854
+ * @internal
855
+ */
856
+ static base64UrlToBigInt(base64Url) {
857
+ if (core.Is.empty(base64Url)) {
858
+ return BigInt(0);
859
+ }
860
+ const bytes = core.Converter.base64UrlToBytes(base64Url);
861
+ const hexString = Array.from(bytes)
862
+ .map(byte => byte.toString(16).padStart(2, "0"))
863
+ .join("");
864
+ return BigInt(`0x${hexString}`);
865
+ }
866
+ /**
867
+ * Encrypt the data using the public key.
868
+ * @param data The data to encrypt.
869
+ * @returns The data encrypted.
870
+ */
871
+ async publicEncrypt(data) {
872
+ core.Guards.uint8Array(RSA._CLASS_NAME, "data", data);
873
+ if (data.length === 0) {
874
+ return new Uint8Array(0);
875
+ }
876
+ const keyDetails = await this.calculateKeyDetails();
877
+ const blocks = [];
878
+ // Split data into blocks of block size
879
+ for (let i = 0; i < data.length; i += keyDetails.blockSize) {
880
+ const block = data.slice(i, i + keyDetails.blockSize);
881
+ const encryptedBlock = node_crypto.publicEncrypt({
882
+ key: keyDetails.publicKey,
883
+ padding: node_crypto.constants.RSA_PKCS1_OAEP_PADDING
884
+ }, block);
885
+ blocks.push(encryptedBlock);
886
+ }
887
+ return core.Uint8ArrayHelper.concat(blocks);
888
+ }
889
+ /**
890
+ * Encrypt the data using the private key.
891
+ * @param data The data to encrypt.
892
+ * @returns The data encrypted.
893
+ */
894
+ async privateEncrypt(data) {
895
+ core.Guards.uint8Array(RSA._CLASS_NAME, "data", data);
896
+ const keyDetails = await this.calculateKeyDetails();
897
+ if (core.Is.empty(keyDetails.privateKey)) {
898
+ throw new core.GeneralError(RSA._CLASS_NAME, "noPrivateKey");
899
+ }
900
+ if (data.length === 0) {
901
+ return new Uint8Array(0);
902
+ }
903
+ const blocks = [];
904
+ // Split data into blocks of block size
905
+ for (let i = 0; i < data.length; i += keyDetails.blockSize) {
906
+ const block = data.slice(i, i + keyDetails.blockSize);
907
+ const encryptedBlock = node_crypto.privateEncrypt({
908
+ key: keyDetails.privateKey,
909
+ padding: node_crypto.constants.RSA_PKCS1_PADDING
910
+ }, block);
911
+ blocks.push(encryptedBlock);
912
+ }
913
+ return core.Uint8ArrayHelper.concat(blocks);
914
+ }
915
+ /**
916
+ * Decrypt the data using the private key.
917
+ * @param data The data to decrypt.
918
+ * @returns The data decrypted.
919
+ * @throws GeneralError If no private key is provided.
920
+ */
921
+ async privateDecrypt(data) {
922
+ core.Guards.uint8Array(RSA._CLASS_NAME, "data", data);
923
+ const keyDetails = await this.calculateKeyDetails();
924
+ if (core.Is.empty(keyDetails.privateKey)) {
925
+ throw new core.GeneralError(RSA._CLASS_NAME, "noPrivateKey");
926
+ }
927
+ if (data.length === 0) {
928
+ return new Uint8Array(0);
929
+ }
930
+ const blocks = [];
931
+ // Split encrypted data into blocks of key size
932
+ for (let i = 0; i < data.length; i += keyDetails.keySize) {
933
+ const block = data.slice(i, i + keyDetails.keySize);
934
+ const decryptedBlock = node_crypto.privateDecrypt({
935
+ key: keyDetails.privateKey,
936
+ padding: node_crypto.constants.RSA_PKCS1_OAEP_PADDING
937
+ }, block);
938
+ blocks.push(decryptedBlock);
939
+ }
940
+ return core.Uint8ArrayHelper.concat(blocks);
941
+ }
942
+ /**
943
+ * Decrypt the data using the public key.
944
+ * @param data The data to decrypt.
945
+ * @returns The data decrypted.
946
+ */
947
+ async publicDecrypt(data) {
948
+ core.Guards.uint8Array(RSA._CLASS_NAME, "data", data);
949
+ const keyDetails = await this.calculateKeyDetails();
950
+ if (data.length === 0) {
951
+ return new Uint8Array(0);
952
+ }
953
+ const blocks = [];
954
+ // Split encrypted data into blocks of key size
955
+ for (let i = 0; i < data.length; i += keyDetails.keySize) {
956
+ const block = data.slice(i, i + keyDetails.keySize);
957
+ const decryptedBlock = node_crypto.publicDecrypt({
958
+ key: keyDetails.publicKey,
959
+ padding: node_crypto.constants.RSA_PKCS1_PADDING
960
+ }, block);
961
+ blocks.push(decryptedBlock);
962
+ }
963
+ return core.Uint8ArrayHelper.concat(blocks);
964
+ }
965
+ /**
966
+ * Calculate key details.
967
+ * @internal
968
+ */
969
+ async calculateKeyDetails() {
970
+ if (core.Is.empty(this._publicKey) || core.Is.empty(this._keySize) || core.Is.empty(this._blockSize)) {
971
+ this._publicKey = node_crypto.createPublicKey({
972
+ key: Buffer.from(this._publicKeyBytes),
973
+ format: "der",
974
+ type: "spki"
975
+ });
976
+ if (!core.Is.empty(this._privateKeyBytes)) {
977
+ this._privateKey = node_crypto.createPrivateKey({
978
+ key: Buffer.from(this._privateKeyBytes),
979
+ format: "der",
980
+ type: "pkcs8"
981
+ });
982
+ }
983
+ // Get modulus length in bits from key details
984
+ const modulusLengthBits = this._publicKey.asymmetricKeyDetails?.modulusLength;
985
+ if (core.Is.empty(modulusLengthBits)) {
986
+ throw new core.GeneralError(RSA._CLASS_NAME, "invalidKeySize");
987
+ }
988
+ // Convert bits to bytes
989
+ this._keySize = Math.ceil(modulusLengthBits / 8);
990
+ // Calculate block size for OAEP with SHA-256
991
+ // Formula: keySize - 2 * hashLength - 2
992
+ const hashLength = 32; // SHA-256 = 32 bytes
993
+ // eslint-disable-next-line no-mixed-operators
994
+ this._blockSize = this._keySize - 2 * hashLength - 2;
995
+ }
996
+ return {
997
+ publicKey: this._publicKey,
998
+ privateKey: this._privateKey,
999
+ keySize: this._keySize,
1000
+ blockSize: this._blockSize
1001
+ };
1002
+ }
1003
+ }
1004
+
1005
+ // Copyright 2024 IOTA Stiftung.
1006
+ // SPDX-License-Identifier: Apache-2.0.
722
1007
  /**
723
1008
  * Implementation of X25519.
724
1009
  */
@@ -1526,6 +1811,48 @@ class Sha512 {
1526
1811
  }
1527
1812
  }
1528
1813
 
1814
+ // Copyright 2024 IOTA Stiftung.
1815
+ // SPDX-License-Identifier: Apache-2.0.
1816
+ /**
1817
+ * Helper class for working with PEM (Privacy-Enhanced Mail) formatted data.
1818
+ */
1819
+ class PemHelper {
1820
+ /**
1821
+ * Runtime name for the class.
1822
+ * @internal
1823
+ */
1824
+ static _CLASS_NAME = "PemHelper";
1825
+ /**
1826
+ * Strip the PEM content of its headers, footers, and newlines.
1827
+ * @param pemContent The PEM content to strip.
1828
+ * @returns The stripped PEM content in bas64 format.
1829
+ */
1830
+ static stripPemMarkers(pemContent) {
1831
+ core.Guards.string(PemHelper._CLASS_NAME, "pemContent", pemContent);
1832
+ return pemContent
1833
+ .replace(/-----BEGIN.*-----/, "")
1834
+ .replace(/-----END.*-----/, "")
1835
+ .replace(/\n/g, "")
1836
+ .trim();
1837
+ }
1838
+ /**
1839
+ * Format the PEM content to have a specific line length.
1840
+ * @param marker The marker for the PEM content, e.g. RSA PRIVATE KEY
1841
+ * @param base64Content The base64 content to format.
1842
+ * @param lineLength The length of each line in the PEM content, default is 64 characters.
1843
+ * @returns The formatted PEM content.
1844
+ */
1845
+ static formatPem(marker, base64Content, lineLength = 64) {
1846
+ core.Guards.stringValue(PemHelper._CLASS_NAME, "marker", marker);
1847
+ core.Guards.stringBase64(PemHelper._CLASS_NAME, "base64Content", base64Content);
1848
+ const lines = [];
1849
+ for (let i = 0; i < base64Content.length; i += lineLength) {
1850
+ lines.push(base64Content.slice(i, i + lineLength));
1851
+ }
1852
+ return [`-----BEGIN ${marker}-----`, ...lines, `-----END ${marker}-----`].join("\n");
1853
+ }
1854
+ }
1855
+
1529
1856
  // Copyright 2024 IOTA Stiftung.
1530
1857
  // SPDX-License-Identifier: Apache-2.0.
1531
1858
  /**
@@ -1812,6 +2139,8 @@ exports.KeyType = KeyType;
1812
2139
  exports.PasswordGenerator = PasswordGenerator;
1813
2140
  exports.PasswordValidator = PasswordValidator;
1814
2141
  exports.Pbkdf2 = Pbkdf2;
2142
+ exports.PemHelper = PemHelper;
2143
+ exports.RSA = RSA;
1815
2144
  exports.Secp256k1 = Secp256k1;
1816
2145
  exports.Sha1 = Sha1;
1817
2146
  exports.Sha256 = Sha256;
@@ -6,6 +6,7 @@ import { blake2b } from '@noble/hashes/blake2b';
6
6
  import { HDKey as HDKey$1 } from '@scure/bip32';
7
7
  import { HDKey } from 'micro-key-producer/slip10.js';
8
8
  import { chacha20poly1305 } from '@noble/ciphers/chacha';
9
+ import { generateKeyPairSync, createPrivateKey, createPublicKey, publicEncrypt, constants, privateEncrypt, privateDecrypt, publicDecrypt } from 'node:crypto';
9
10
  import { blake3 } from '@noble/hashes/blake3';
10
11
  import { hmac } from '@noble/hashes/hmac';
11
12
  import { sha1 } from '@noble/hashes/sha1';
@@ -695,8 +696,292 @@ class ChaCha20Poly1305 {
695
696
  // Copyright 2024 IOTA Stiftung.
696
697
  // SPDX-License-Identifier: Apache-2.0.
697
698
  /**
698
- * This is a TypeScript port of https://github.com/katzenpost/core/blob/master/crypto/extra25519/extra25519.go.
699
+ * Implementation of the RSA cipher.
699
700
  */
701
+ class RSA {
702
+ /**
703
+ * Runtime name for the class.
704
+ * @internal
705
+ */
706
+ static _CLASS_NAME = "RSA";
707
+ /**
708
+ * The public key for encryption.
709
+ * @internal
710
+ */
711
+ _publicKeyBytes;
712
+ /**
713
+ * The private key for decryption.
714
+ * @internal
715
+ */
716
+ _privateKeyBytes;
717
+ /**
718
+ * The public key for encryption.
719
+ * @internal
720
+ */
721
+ _publicKey;
722
+ /**
723
+ * The private key for decryption.
724
+ * @internal
725
+ */
726
+ _privateKey;
727
+ /**
728
+ * The block size for encryption.
729
+ * @internal
730
+ */
731
+ _blockSize;
732
+ /**
733
+ * The key size for decryption.
734
+ * @internal
735
+ */
736
+ _keySize;
737
+ /**
738
+ * Create a new instance of RSA.
739
+ * @param publicKey The public key for encryption (DER format as Uint8Array).
740
+ * @param privateKey The private key for decryption (DER format as Uint8Array).
741
+ */
742
+ constructor(publicKey, privateKey) {
743
+ Guards.uint8Array(RSA._CLASS_NAME, "publicKey", publicKey);
744
+ this._publicKeyBytes = publicKey;
745
+ this._privateKeyBytes = privateKey;
746
+ }
747
+ /**
748
+ * Generate a new RSA key pair in PKCS8 format.
749
+ * @param modulusLength The key size in bits (default: 2048).
750
+ * @returns The public and private keys as Uint8Array.
751
+ */
752
+ static async generateKeyPair(modulusLength = 2048) {
753
+ const { publicKey, privateKey } = generateKeyPairSync("rsa", {
754
+ modulusLength,
755
+ publicKeyEncoding: {
756
+ type: "spki",
757
+ format: "der"
758
+ },
759
+ privateKeyEncoding: {
760
+ type: "pkcs8",
761
+ format: "der"
762
+ }
763
+ });
764
+ return {
765
+ publicKey: new Uint8Array(publicKey),
766
+ privateKey: new Uint8Array(privateKey)
767
+ };
768
+ }
769
+ /**
770
+ * Convert a PKCS1 key to a PKCS8 key.
771
+ * @param pkcs1Key The PKCS1 key as Uint8Array.
772
+ * @returns The PKCS8 key as Uint8Array.
773
+ */
774
+ static async convertPkcs1ToPkcs8(pkcs1Key) {
775
+ Guards.uint8Array(RSA._CLASS_NAME, "pkcs1Key", pkcs1Key);
776
+ const privateKey = createPrivateKey({
777
+ key: Buffer.from(pkcs1Key),
778
+ format: "der",
779
+ type: "pkcs1"
780
+ });
781
+ return new Uint8Array(privateKey.export({
782
+ format: "der",
783
+ type: "pkcs8"
784
+ }));
785
+ }
786
+ /**
787
+ * Break the private key down in to its components.
788
+ * @param pkcs8Key The PKCS8 key as Uint8Array.
789
+ * @returns The key components.
790
+ */
791
+ static async getPrivateKeyComponents(pkcs8Key) {
792
+ Guards.uint8Array(RSA._CLASS_NAME, "pkcs8Key", pkcs8Key);
793
+ const privateKey = createPrivateKey({
794
+ key: Buffer.from(pkcs8Key),
795
+ format: "der",
796
+ type: "pkcs8"
797
+ });
798
+ const jwk = privateKey.export({ format: "jwk" });
799
+ return {
800
+ n: this.base64UrlToBigInt(jwk.n),
801
+ e: this.base64UrlToBigInt(jwk.e),
802
+ d: this.base64UrlToBigInt(jwk.d),
803
+ p: this.base64UrlToBigInt(jwk.p),
804
+ q: this.base64UrlToBigInt(jwk.q),
805
+ dp: this.base64UrlToBigInt(jwk.dp),
806
+ dq: this.base64UrlToBigInt(jwk.dq),
807
+ qi: this.base64UrlToBigInt(jwk.qi)
808
+ };
809
+ }
810
+ /**
811
+ * Break the public key down in to its components.
812
+ * @param spkiKey The SPKI key as Uint8Array.
813
+ * @returns The key components.
814
+ */
815
+ static async getPublicKeyComponents(spkiKey) {
816
+ Guards.uint8Array(RSA._CLASS_NAME, "spkiKey", spkiKey);
817
+ const publicKey = createPublicKey({
818
+ key: Buffer.from(spkiKey),
819
+ format: "der",
820
+ type: "spki"
821
+ });
822
+ const jwk = publicKey.export({ format: "jwk" });
823
+ return {
824
+ n: this.base64UrlToBigInt(jwk.n),
825
+ e: this.base64UrlToBigInt(jwk.e)
826
+ };
827
+ }
828
+ /**
829
+ * Convert base64 encoded data to a big int.
830
+ * @param bytes The bytes to convert.
831
+ * @returns The bigint representation of the bytes.
832
+ * @internal
833
+ */
834
+ static base64UrlToBigInt(base64Url) {
835
+ if (Is.empty(base64Url)) {
836
+ return BigInt(0);
837
+ }
838
+ const bytes = Converter.base64UrlToBytes(base64Url);
839
+ const hexString = Array.from(bytes)
840
+ .map(byte => byte.toString(16).padStart(2, "0"))
841
+ .join("");
842
+ return BigInt(`0x${hexString}`);
843
+ }
844
+ /**
845
+ * Encrypt the data using the public key.
846
+ * @param data The data to encrypt.
847
+ * @returns The data encrypted.
848
+ */
849
+ async publicEncrypt(data) {
850
+ Guards.uint8Array(RSA._CLASS_NAME, "data", data);
851
+ if (data.length === 0) {
852
+ return new Uint8Array(0);
853
+ }
854
+ const keyDetails = await this.calculateKeyDetails();
855
+ const blocks = [];
856
+ // Split data into blocks of block size
857
+ for (let i = 0; i < data.length; i += keyDetails.blockSize) {
858
+ const block = data.slice(i, i + keyDetails.blockSize);
859
+ const encryptedBlock = publicEncrypt({
860
+ key: keyDetails.publicKey,
861
+ padding: constants.RSA_PKCS1_OAEP_PADDING
862
+ }, block);
863
+ blocks.push(encryptedBlock);
864
+ }
865
+ return Uint8ArrayHelper.concat(blocks);
866
+ }
867
+ /**
868
+ * Encrypt the data using the private key.
869
+ * @param data The data to encrypt.
870
+ * @returns The data encrypted.
871
+ */
872
+ async privateEncrypt(data) {
873
+ Guards.uint8Array(RSA._CLASS_NAME, "data", data);
874
+ const keyDetails = await this.calculateKeyDetails();
875
+ if (Is.empty(keyDetails.privateKey)) {
876
+ throw new GeneralError(RSA._CLASS_NAME, "noPrivateKey");
877
+ }
878
+ if (data.length === 0) {
879
+ return new Uint8Array(0);
880
+ }
881
+ const blocks = [];
882
+ // Split data into blocks of block size
883
+ for (let i = 0; i < data.length; i += keyDetails.blockSize) {
884
+ const block = data.slice(i, i + keyDetails.blockSize);
885
+ const encryptedBlock = privateEncrypt({
886
+ key: keyDetails.privateKey,
887
+ padding: constants.RSA_PKCS1_PADDING
888
+ }, block);
889
+ blocks.push(encryptedBlock);
890
+ }
891
+ return Uint8ArrayHelper.concat(blocks);
892
+ }
893
+ /**
894
+ * Decrypt the data using the private key.
895
+ * @param data The data to decrypt.
896
+ * @returns The data decrypted.
897
+ * @throws GeneralError If no private key is provided.
898
+ */
899
+ async privateDecrypt(data) {
900
+ Guards.uint8Array(RSA._CLASS_NAME, "data", data);
901
+ const keyDetails = await this.calculateKeyDetails();
902
+ if (Is.empty(keyDetails.privateKey)) {
903
+ throw new GeneralError(RSA._CLASS_NAME, "noPrivateKey");
904
+ }
905
+ if (data.length === 0) {
906
+ return new Uint8Array(0);
907
+ }
908
+ const blocks = [];
909
+ // Split encrypted data into blocks of key size
910
+ for (let i = 0; i < data.length; i += keyDetails.keySize) {
911
+ const block = data.slice(i, i + keyDetails.keySize);
912
+ const decryptedBlock = privateDecrypt({
913
+ key: keyDetails.privateKey,
914
+ padding: constants.RSA_PKCS1_OAEP_PADDING
915
+ }, block);
916
+ blocks.push(decryptedBlock);
917
+ }
918
+ return Uint8ArrayHelper.concat(blocks);
919
+ }
920
+ /**
921
+ * Decrypt the data using the public key.
922
+ * @param data The data to decrypt.
923
+ * @returns The data decrypted.
924
+ */
925
+ async publicDecrypt(data) {
926
+ Guards.uint8Array(RSA._CLASS_NAME, "data", data);
927
+ const keyDetails = await this.calculateKeyDetails();
928
+ if (data.length === 0) {
929
+ return new Uint8Array(0);
930
+ }
931
+ const blocks = [];
932
+ // Split encrypted data into blocks of key size
933
+ for (let i = 0; i < data.length; i += keyDetails.keySize) {
934
+ const block = data.slice(i, i + keyDetails.keySize);
935
+ const decryptedBlock = publicDecrypt({
936
+ key: keyDetails.publicKey,
937
+ padding: constants.RSA_PKCS1_PADDING
938
+ }, block);
939
+ blocks.push(decryptedBlock);
940
+ }
941
+ return Uint8ArrayHelper.concat(blocks);
942
+ }
943
+ /**
944
+ * Calculate key details.
945
+ * @internal
946
+ */
947
+ async calculateKeyDetails() {
948
+ if (Is.empty(this._publicKey) || Is.empty(this._keySize) || Is.empty(this._blockSize)) {
949
+ this._publicKey = createPublicKey({
950
+ key: Buffer.from(this._publicKeyBytes),
951
+ format: "der",
952
+ type: "spki"
953
+ });
954
+ if (!Is.empty(this._privateKeyBytes)) {
955
+ this._privateKey = createPrivateKey({
956
+ key: Buffer.from(this._privateKeyBytes),
957
+ format: "der",
958
+ type: "pkcs8"
959
+ });
960
+ }
961
+ // Get modulus length in bits from key details
962
+ const modulusLengthBits = this._publicKey.asymmetricKeyDetails?.modulusLength;
963
+ if (Is.empty(modulusLengthBits)) {
964
+ throw new GeneralError(RSA._CLASS_NAME, "invalidKeySize");
965
+ }
966
+ // Convert bits to bytes
967
+ this._keySize = Math.ceil(modulusLengthBits / 8);
968
+ // Calculate block size for OAEP with SHA-256
969
+ // Formula: keySize - 2 * hashLength - 2
970
+ const hashLength = 32; // SHA-256 = 32 bytes
971
+ // eslint-disable-next-line no-mixed-operators
972
+ this._blockSize = this._keySize - 2 * hashLength - 2;
973
+ }
974
+ return {
975
+ publicKey: this._publicKey,
976
+ privateKey: this._privateKey,
977
+ keySize: this._keySize,
978
+ blockSize: this._blockSize
979
+ };
980
+ }
981
+ }
982
+
983
+ // Copyright 2024 IOTA Stiftung.
984
+ // SPDX-License-Identifier: Apache-2.0.
700
985
  /**
701
986
  * Implementation of X25519.
702
987
  */
@@ -1504,6 +1789,48 @@ class Sha512 {
1504
1789
  }
1505
1790
  }
1506
1791
 
1792
+ // Copyright 2024 IOTA Stiftung.
1793
+ // SPDX-License-Identifier: Apache-2.0.
1794
+ /**
1795
+ * Helper class for working with PEM (Privacy-Enhanced Mail) formatted data.
1796
+ */
1797
+ class PemHelper {
1798
+ /**
1799
+ * Runtime name for the class.
1800
+ * @internal
1801
+ */
1802
+ static _CLASS_NAME = "PemHelper";
1803
+ /**
1804
+ * Strip the PEM content of its headers, footers, and newlines.
1805
+ * @param pemContent The PEM content to strip.
1806
+ * @returns The stripped PEM content in bas64 format.
1807
+ */
1808
+ static stripPemMarkers(pemContent) {
1809
+ Guards.string(PemHelper._CLASS_NAME, "pemContent", pemContent);
1810
+ return pemContent
1811
+ .replace(/-----BEGIN.*-----/, "")
1812
+ .replace(/-----END.*-----/, "")
1813
+ .replace(/\n/g, "")
1814
+ .trim();
1815
+ }
1816
+ /**
1817
+ * Format the PEM content to have a specific line length.
1818
+ * @param marker The marker for the PEM content, e.g. RSA PRIVATE KEY
1819
+ * @param base64Content The base64 content to format.
1820
+ * @param lineLength The length of each line in the PEM content, default is 64 characters.
1821
+ * @returns The formatted PEM content.
1822
+ */
1823
+ static formatPem(marker, base64Content, lineLength = 64) {
1824
+ Guards.stringValue(PemHelper._CLASS_NAME, "marker", marker);
1825
+ Guards.stringBase64(PemHelper._CLASS_NAME, "base64Content", base64Content);
1826
+ const lines = [];
1827
+ for (let i = 0; i < base64Content.length; i += lineLength) {
1828
+ lines.push(base64Content.slice(i, i + lineLength));
1829
+ }
1830
+ return [`-----BEGIN ${marker}-----`, ...lines, `-----END ${marker}-----`].join("\n");
1831
+ }
1832
+ }
1833
+
1507
1834
  // Copyright 2024 IOTA Stiftung.
1508
1835
  // SPDX-License-Identifier: Apache-2.0.
1509
1836
  /**
@@ -1774,4 +2101,4 @@ class PasswordValidator {
1774
2101
  }
1775
2102
  }
1776
2103
 
1777
- export { Bech32, Bip32Path, Bip39, Bip44, Blake2b, Blake3, ChaCha20Poly1305, Ed25519, HmacSha1, HmacSha256, HmacSha512, Hotp, KeyType, PasswordGenerator, PasswordValidator, Pbkdf2, Secp256k1, Sha1, Sha256, Sha3, Sha512, Slip0010, Totp, X25519, Zip215 };
2104
+ export { Bech32, Bip32Path, Bip39, Bip44, Blake2b, Blake3, ChaCha20Poly1305, Ed25519, HmacSha1, HmacSha256, HmacSha512, Hotp, KeyType, PasswordGenerator, PasswordValidator, Pbkdf2, PemHelper, RSA, Secp256k1, Sha1, Sha256, Sha3, Sha512, Slip0010, Totp, X25519, Zip215 };
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Implementation of the RSA cipher.
3
+ */
4
+ export declare class RSA {
5
+ /**
6
+ * Create a new instance of RSA.
7
+ * @param publicKey The public key for encryption (DER format as Uint8Array).
8
+ * @param privateKey The private key for decryption (DER format as Uint8Array).
9
+ */
10
+ constructor(publicKey: Uint8Array, privateKey?: Uint8Array);
11
+ /**
12
+ * Generate a new RSA key pair in PKCS8 format.
13
+ * @param modulusLength The key size in bits (default: 2048).
14
+ * @returns The public and private keys as Uint8Array.
15
+ */
16
+ static generateKeyPair(modulusLength?: number): Promise<{
17
+ publicKey: Uint8Array;
18
+ privateKey: Uint8Array;
19
+ }>;
20
+ /**
21
+ * Convert a PKCS1 key to a PKCS8 key.
22
+ * @param pkcs1Key The PKCS1 key as Uint8Array.
23
+ * @returns The PKCS8 key as Uint8Array.
24
+ */
25
+ static convertPkcs1ToPkcs8(pkcs1Key: Uint8Array): Promise<Uint8Array>;
26
+ /**
27
+ * Break the private key down in to its components.
28
+ * @param pkcs8Key The PKCS8 key as Uint8Array.
29
+ * @returns The key components.
30
+ */
31
+ static getPrivateKeyComponents(pkcs8Key: Uint8Array): Promise<{
32
+ n: bigint;
33
+ e: bigint;
34
+ d: bigint;
35
+ p: bigint;
36
+ q: bigint;
37
+ dp: bigint;
38
+ dq: bigint;
39
+ qi: bigint;
40
+ }>;
41
+ /**
42
+ * Break the public key down in to its components.
43
+ * @param spkiKey The SPKI key as Uint8Array.
44
+ * @returns The key components.
45
+ */
46
+ static getPublicKeyComponents(spkiKey: Uint8Array): Promise<{
47
+ n: bigint;
48
+ e: bigint;
49
+ }>;
50
+ /**
51
+ * Encrypt the data using the public key.
52
+ * @param data The data to encrypt.
53
+ * @returns The data encrypted.
54
+ */
55
+ publicEncrypt(data: Uint8Array): Promise<Uint8Array>;
56
+ /**
57
+ * Encrypt the data using the private key.
58
+ * @param data The data to encrypt.
59
+ * @returns The data encrypted.
60
+ */
61
+ privateEncrypt(data: Uint8Array): Promise<Uint8Array>;
62
+ /**
63
+ * Decrypt the data using the private key.
64
+ * @param data The data to decrypt.
65
+ * @returns The data decrypted.
66
+ * @throws GeneralError If no private key is provided.
67
+ */
68
+ privateDecrypt(data: Uint8Array): Promise<Uint8Array>;
69
+ /**
70
+ * Decrypt the data using the public key.
71
+ * @param data The data to decrypt.
72
+ * @returns The data decrypted.
73
+ */
74
+ publicDecrypt(data: Uint8Array): Promise<Uint8Array>;
75
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Helper class for working with PEM (Privacy-Enhanced Mail) formatted data.
3
+ */
4
+ export declare class PemHelper {
5
+ /**
6
+ * Strip the PEM content of its headers, footers, and newlines.
7
+ * @param pemContent The PEM content to strip.
8
+ * @returns The stripped PEM content in bas64 format.
9
+ */
10
+ static stripPemMarkers(pemContent: string): string;
11
+ /**
12
+ * Format the PEM content to have a specific line length.
13
+ * @param marker The marker for the PEM content, e.g. RSA PRIVATE KEY
14
+ * @param base64Content The base64 content to format.
15
+ * @param lineLength The length of each line in the PEM content, default is 64 characters.
16
+ * @returns The formatted PEM content.
17
+ */
18
+ static formatPem(marker: string, base64Content: string, lineLength?: number): string;
19
+ }
@@ -1,6 +1,7 @@
1
1
  export * from "./address/bech32";
2
2
  export * from "./address/bip44";
3
3
  export * from "./ciphers/chaCha20Poly1305";
4
+ export * from "./ciphers/rsa";
4
5
  export * from "./curves/ed25519";
5
6
  export * from "./curves/secp256k1";
6
7
  export * from "./curves/x25519";
@@ -15,6 +16,7 @@ export * from "./hashes/sha1";
15
16
  export * from "./hashes/sha256";
16
17
  export * from "./hashes/sha3";
17
18
  export * from "./hashes/sha512";
19
+ export * from "./helpers/pemHelper";
18
20
  export * from "./keys/bip32Path";
19
21
  export * from "./keys/bip39";
20
22
  export * from "./keys/slip0010";
package/docs/changelog.md CHANGED
@@ -1,5 +1,92 @@
1
1
  # @twin.org/crypto - Changelog
2
2
 
3
+ ## [0.0.2-next.4](https://github.com/twinfoundation/framework/compare/crypto-v0.0.2-next.3...crypto-v0.0.2-next.4) (2025-08-15)
4
+
5
+
6
+ ### Features
7
+
8
+ * additional RSA methods and async ([1fceee2](https://github.com/twinfoundation/framework/commit/1fceee2d1248a24a7620846025fcf906495c07f4))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/core bumped from 0.0.2-next.3 to 0.0.2-next.4
16
+ * @twin.org/nameof bumped from 0.0.2-next.3 to 0.0.2-next.4
17
+ * devDependencies
18
+ * @twin.org/nameof-transformer bumped from 0.0.2-next.3 to 0.0.2-next.4
19
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.2-next.3 to 0.0.2-next.4
20
+
21
+ ## [0.0.2-next.3](https://github.com/twinfoundation/framework/compare/crypto-v0.0.2-next.2...crypto-v0.0.2-next.3) (2025-08-06)
22
+
23
+
24
+ ### Features
25
+
26
+ * add guards arrayEndsWith and arrayStartsWith ([95d875e](https://github.com/twinfoundation/framework/commit/95d875ec8ccb4713c145fdde941d4cfedcec2ed3))
27
+ * add rsa cipher support ([7af6cc6](https://github.com/twinfoundation/framework/commit/7af6cc67512d3363bd4a2f2e87bd7733c2800147))
28
+ * add RSA support for public key components ([7126259](https://github.com/twinfoundation/framework/commit/7126259103b758c291e52a8a03818eb822d1aad1))
29
+ * change method accessibility ([c1b77fc](https://github.com/twinfoundation/framework/commit/c1b77fcfb61c092a01c97aebb2fe2dc2bbaa221b))
30
+ * relocate core packages from tools ([bcab8f3](https://github.com/twinfoundation/framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
31
+ * update dependencies ([f3bd015](https://github.com/twinfoundation/framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
32
+ * use new shared store mechanism ([#131](https://github.com/twinfoundation/framework/issues/131)) ([934385b](https://github.com/twinfoundation/framework/commit/934385b2fbaf9f5c00a505ebf9d093bd5a425f55))
33
+
34
+
35
+ ### Dependencies
36
+
37
+ * The following workspace dependencies were updated
38
+ * dependencies
39
+ * @twin.org/core bumped from 0.0.2-next.2 to 0.0.2-next.3
40
+ * @twin.org/nameof bumped from 0.0.2-next.2 to 0.0.2-next.3
41
+ * devDependencies
42
+ * @twin.org/nameof-transformer bumped from 0.0.2-next.2 to 0.0.2-next.3
43
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.2-next.2 to 0.0.2-next.3
44
+
45
+ ## [0.0.2-next.2](https://github.com/twinfoundation/framework/compare/crypto-v0.0.2-next.1...crypto-v0.0.2-next.2) (2025-08-06)
46
+
47
+
48
+ ### Features
49
+
50
+ * add guards arrayEndsWith and arrayStartsWith ([95d875e](https://github.com/twinfoundation/framework/commit/95d875ec8ccb4713c145fdde941d4cfedcec2ed3))
51
+ * add rsa cipher support ([7af6cc6](https://github.com/twinfoundation/framework/commit/7af6cc67512d3363bd4a2f2e87bd7733c2800147))
52
+ * change method accessibility ([c1b77fc](https://github.com/twinfoundation/framework/commit/c1b77fcfb61c092a01c97aebb2fe2dc2bbaa221b))
53
+ * relocate core packages from tools ([bcab8f3](https://github.com/twinfoundation/framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
54
+ * update dependencies ([f3bd015](https://github.com/twinfoundation/framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
55
+ * use new shared store mechanism ([#131](https://github.com/twinfoundation/framework/issues/131)) ([934385b](https://github.com/twinfoundation/framework/commit/934385b2fbaf9f5c00a505ebf9d093bd5a425f55))
56
+
57
+
58
+ ### Dependencies
59
+
60
+ * The following workspace dependencies were updated
61
+ * dependencies
62
+ * @twin.org/core bumped from 0.0.2-next.1 to 0.0.2-next.2
63
+ * @twin.org/nameof bumped from 0.0.2-next.1 to 0.0.2-next.2
64
+ * devDependencies
65
+ * @twin.org/nameof-transformer bumped from 0.0.2-next.1 to 0.0.2-next.2
66
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.2-next.1 to 0.0.2-next.2
67
+
68
+ ## [0.0.2-next.1](https://github.com/twinfoundation/framework/compare/crypto-v0.0.2-next.0...crypto-v0.0.2-next.1) (2025-08-06)
69
+
70
+
71
+ ### Features
72
+
73
+ * add guards arrayEndsWith and arrayStartsWith ([95d875e](https://github.com/twinfoundation/framework/commit/95d875ec8ccb4713c145fdde941d4cfedcec2ed3))
74
+ * add rsa cipher support ([7af6cc6](https://github.com/twinfoundation/framework/commit/7af6cc67512d3363bd4a2f2e87bd7733c2800147))
75
+ * relocate core packages from tools ([bcab8f3](https://github.com/twinfoundation/framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
76
+ * update dependencies ([f3bd015](https://github.com/twinfoundation/framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
77
+ * use new shared store mechanism ([#131](https://github.com/twinfoundation/framework/issues/131)) ([934385b](https://github.com/twinfoundation/framework/commit/934385b2fbaf9f5c00a505ebf9d093bd5a425f55))
78
+
79
+
80
+ ### Dependencies
81
+
82
+ * The following workspace dependencies were updated
83
+ * dependencies
84
+ * @twin.org/core bumped from 0.0.2-next.0 to 0.0.2-next.1
85
+ * @twin.org/nameof bumped from 0.0.2-next.0 to 0.0.2-next.1
86
+ * devDependencies
87
+ * @twin.org/nameof-transformer bumped from 0.0.2-next.0 to 0.0.2-next.1
88
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.2-next.0 to 0.0.2-next.1
89
+
3
90
  ## 0.0.1 (2025-07-03)
4
91
 
5
92
 
@@ -0,0 +1,69 @@
1
+ # Class: PemHelper
2
+
3
+ Helper class for working with PEM (Privacy-Enhanced Mail) formatted data.
4
+
5
+ ## Constructors
6
+
7
+ ### Constructor
8
+
9
+ > **new PemHelper**(): `PemHelper`
10
+
11
+ #### Returns
12
+
13
+ `PemHelper`
14
+
15
+ ## Methods
16
+
17
+ ### stripPemMarkers()
18
+
19
+ > `static` **stripPemMarkers**(`pemContent`): `string`
20
+
21
+ Strip the PEM content of its headers, footers, and newlines.
22
+
23
+ #### Parameters
24
+
25
+ ##### pemContent
26
+
27
+ `string`
28
+
29
+ The PEM content to strip.
30
+
31
+ #### Returns
32
+
33
+ `string`
34
+
35
+ The stripped PEM content in bas64 format.
36
+
37
+ ***
38
+
39
+ ### formatPem()
40
+
41
+ > `static` **formatPem**(`marker`, `base64Content`, `lineLength`): `string`
42
+
43
+ Format the PEM content to have a specific line length.
44
+
45
+ #### Parameters
46
+
47
+ ##### marker
48
+
49
+ `string`
50
+
51
+ The marker for the PEM content, e.g. RSA PRIVATE KEY
52
+
53
+ ##### base64Content
54
+
55
+ `string`
56
+
57
+ The base64 content to format.
58
+
59
+ ##### lineLength
60
+
61
+ `number` = `64`
62
+
63
+ The length of each line in the PEM content, default is 64 characters.
64
+
65
+ #### Returns
66
+
67
+ `string`
68
+
69
+ The formatted PEM content.
@@ -0,0 +1,209 @@
1
+ # Class: RSA
2
+
3
+ Implementation of the RSA cipher.
4
+
5
+ ## Constructors
6
+
7
+ ### Constructor
8
+
9
+ > **new RSA**(`publicKey`, `privateKey?`): `RSA`
10
+
11
+ Create a new instance of RSA.
12
+
13
+ #### Parameters
14
+
15
+ ##### publicKey
16
+
17
+ `Uint8Array`
18
+
19
+ The public key for encryption (DER format as Uint8Array).
20
+
21
+ ##### privateKey?
22
+
23
+ `Uint8Array`\<`ArrayBufferLike`\>
24
+
25
+ The private key for decryption (DER format as Uint8Array).
26
+
27
+ #### Returns
28
+
29
+ `RSA`
30
+
31
+ ## Methods
32
+
33
+ ### generateKeyPair()
34
+
35
+ > `static` **generateKeyPair**(`modulusLength`): `Promise`\<\{ `publicKey`: `Uint8Array`; `privateKey`: `Uint8Array`; \}\>
36
+
37
+ Generate a new RSA key pair in PKCS8 format.
38
+
39
+ #### Parameters
40
+
41
+ ##### modulusLength
42
+
43
+ `number` = `2048`
44
+
45
+ The key size in bits (default: 2048).
46
+
47
+ #### Returns
48
+
49
+ `Promise`\<\{ `publicKey`: `Uint8Array`; `privateKey`: `Uint8Array`; \}\>
50
+
51
+ The public and private keys as Uint8Array.
52
+
53
+ ***
54
+
55
+ ### convertPkcs1ToPkcs8()
56
+
57
+ > `static` **convertPkcs1ToPkcs8**(`pkcs1Key`): `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
58
+
59
+ Convert a PKCS1 key to a PKCS8 key.
60
+
61
+ #### Parameters
62
+
63
+ ##### pkcs1Key
64
+
65
+ `Uint8Array`
66
+
67
+ The PKCS1 key as Uint8Array.
68
+
69
+ #### Returns
70
+
71
+ `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
72
+
73
+ The PKCS8 key as Uint8Array.
74
+
75
+ ***
76
+
77
+ ### getPrivateKeyComponents()
78
+
79
+ > `static` **getPrivateKeyComponents**(`pkcs8Key`): `Promise`\<\{ `n`: `bigint`; `e`: `bigint`; `d`: `bigint`; `p`: `bigint`; `q`: `bigint`; `dp`: `bigint`; `dq`: `bigint`; `qi`: `bigint`; \}\>
80
+
81
+ Break the private key down in to its components.
82
+
83
+ #### Parameters
84
+
85
+ ##### pkcs8Key
86
+
87
+ `Uint8Array`
88
+
89
+ The PKCS8 key as Uint8Array.
90
+
91
+ #### Returns
92
+
93
+ `Promise`\<\{ `n`: `bigint`; `e`: `bigint`; `d`: `bigint`; `p`: `bigint`; `q`: `bigint`; `dp`: `bigint`; `dq`: `bigint`; `qi`: `bigint`; \}\>
94
+
95
+ The key components.
96
+
97
+ ***
98
+
99
+ ### getPublicKeyComponents()
100
+
101
+ > `static` **getPublicKeyComponents**(`spkiKey`): `Promise`\<\{ `n`: `bigint`; `e`: `bigint`; \}\>
102
+
103
+ Break the public key down in to its components.
104
+
105
+ #### Parameters
106
+
107
+ ##### spkiKey
108
+
109
+ `Uint8Array`
110
+
111
+ The SPKI key as Uint8Array.
112
+
113
+ #### Returns
114
+
115
+ `Promise`\<\{ `n`: `bigint`; `e`: `bigint`; \}\>
116
+
117
+ The key components.
118
+
119
+ ***
120
+
121
+ ### publicEncrypt()
122
+
123
+ > **publicEncrypt**(`data`): `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
124
+
125
+ Encrypt the data using the public key.
126
+
127
+ #### Parameters
128
+
129
+ ##### data
130
+
131
+ `Uint8Array`
132
+
133
+ The data to encrypt.
134
+
135
+ #### Returns
136
+
137
+ `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
138
+
139
+ The data encrypted.
140
+
141
+ ***
142
+
143
+ ### privateEncrypt()
144
+
145
+ > **privateEncrypt**(`data`): `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
146
+
147
+ Encrypt the data using the private key.
148
+
149
+ #### Parameters
150
+
151
+ ##### data
152
+
153
+ `Uint8Array`
154
+
155
+ The data to encrypt.
156
+
157
+ #### Returns
158
+
159
+ `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
160
+
161
+ The data encrypted.
162
+
163
+ ***
164
+
165
+ ### privateDecrypt()
166
+
167
+ > **privateDecrypt**(`data`): `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
168
+
169
+ Decrypt the data using the private key.
170
+
171
+ #### Parameters
172
+
173
+ ##### data
174
+
175
+ `Uint8Array`
176
+
177
+ The data to decrypt.
178
+
179
+ #### Returns
180
+
181
+ `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
182
+
183
+ The data decrypted.
184
+
185
+ #### Throws
186
+
187
+ GeneralError If no private key is provided.
188
+
189
+ ***
190
+
191
+ ### publicDecrypt()
192
+
193
+ > **publicDecrypt**(`data`): `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
194
+
195
+ Decrypt the data using the public key.
196
+
197
+ #### Parameters
198
+
199
+ ##### data
200
+
201
+ `Uint8Array`
202
+
203
+ The data to decrypt.
204
+
205
+ #### Returns
206
+
207
+ `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>
208
+
209
+ The data decrypted.
@@ -5,6 +5,7 @@
5
5
  - [Bech32](classes/Bech32.md)
6
6
  - [Bip44](classes/Bip44.md)
7
7
  - [ChaCha20Poly1305](classes/ChaCha20Poly1305.md)
8
+ - [RSA](classes/RSA.md)
8
9
  - [Ed25519](classes/Ed25519.md)
9
10
  - [Secp256k1](classes/Secp256k1.md)
10
11
  - [X25519](classes/X25519.md)
@@ -19,6 +20,7 @@
19
20
  - [Sha256](classes/Sha256.md)
20
21
  - [Sha3](classes/Sha3.md)
21
22
  - [Sha512](classes/Sha512.md)
23
+ - [PemHelper](classes/PemHelper.md)
22
24
  - [Bip32Path](classes/Bip32Path.md)
23
25
  - [Bip39](classes/Bip39.md)
24
26
  - [Slip0010](classes/Slip0010.md)
package/locales/en.json CHANGED
@@ -63,6 +63,10 @@
63
63
  },
64
64
  "slip0010": {
65
65
  "invalidSeed": "The seed is invalid \"{seed}\""
66
+ },
67
+ "rsa": {
68
+ "noPrivateKey": "Private key is required for this operation",
69
+ "invalidKeySize": "Invalid RSA key size"
66
70
  }
67
71
  }
68
72
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/crypto",
3
- "version": "0.0.1",
3
+ "version": "0.0.2-next.4",
4
4
  "description": "Contains helper methods and classes which implement cryptographic functions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,8 +20,9 @@
20
20
  "@scure/base": "1.2.6",
21
21
  "@scure/bip32": "1.7.0",
22
22
  "@scure/bip39": "1.6.0",
23
- "@twin.org/core": "^0.0.1",
24
- "@twin.org/nameof": "^0.0.1",
23
+ "@twin.org/core": "0.0.2-next.4",
24
+ "@twin.org/nameof": "0.0.2-next.4",
25
+ "crypto-browserify": "3.12.1",
25
26
  "micro-key-producer": "0.7.6"
26
27
  },
27
28
  "main": "./dist/cjs/index.cjs",