@peerbit/crypto 1.0.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.
Files changed (83) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +3 -0
  3. package/lib/esm/bytes.d.ts +5 -0
  4. package/lib/esm/bytes.js +15 -0
  5. package/lib/esm/bytes.js.map +1 -0
  6. package/lib/esm/ed25519-sign-browser.d.ts +5 -0
  7. package/lib/esm/ed25519-sign-browser.js +27 -0
  8. package/lib/esm/ed25519-sign-browser.js.map +1 -0
  9. package/lib/esm/ed25519-sign.d.ts +5 -0
  10. package/lib/esm/ed25519-sign.js +64 -0
  11. package/lib/esm/ed25519-sign.js.map +1 -0
  12. package/lib/esm/ed25519.d.ts +41 -0
  13. package/lib/esm/ed25519.js +181 -0
  14. package/lib/esm/ed25519.js.map +1 -0
  15. package/lib/esm/encryption.d.ts +76 -0
  16. package/lib/esm/encryption.js +350 -0
  17. package/lib/esm/encryption.js.map +1 -0
  18. package/lib/esm/errors.d.ts +3 -0
  19. package/lib/esm/errors.js +6 -0
  20. package/lib/esm/errors.js.map +1 -0
  21. package/lib/esm/hash-browser.d.ts +4 -0
  22. package/lib/esm/hash-browser.js +7 -0
  23. package/lib/esm/hash-browser.js.map +1 -0
  24. package/lib/esm/hash.d.ts +4 -0
  25. package/lib/esm/hash.js +6 -0
  26. package/lib/esm/hash.js.map +1 -0
  27. package/lib/esm/index.d.ts +14 -0
  28. package/lib/esm/index.js +15 -0
  29. package/lib/esm/index.js.map +1 -0
  30. package/lib/esm/key.d.ts +44 -0
  31. package/lib/esm/key.js +51 -0
  32. package/lib/esm/key.js.map +1 -0
  33. package/lib/esm/keychain.d.ts +30 -0
  34. package/lib/esm/keychain.js +142 -0
  35. package/lib/esm/keychain.js.map +1 -0
  36. package/lib/esm/libp2p.d.ts +5 -0
  37. package/lib/esm/libp2p.js +21 -0
  38. package/lib/esm/libp2p.js.map +1 -0
  39. package/lib/esm/prehash.d.ts +6 -0
  40. package/lib/esm/prehash.js +32 -0
  41. package/lib/esm/prehash.js.map +1 -0
  42. package/lib/esm/random-browser.d.ts +1 -0
  43. package/lib/esm/random-browser.js +2 -0
  44. package/lib/esm/random-browser.js.map +1 -0
  45. package/lib/esm/random.d.ts +2 -0
  46. package/lib/esm/random.js +3 -0
  47. package/lib/esm/random.js.map +1 -0
  48. package/lib/esm/sepc256k1.d.ts +42 -0
  49. package/lib/esm/sepc256k1.js +194 -0
  50. package/lib/esm/sepc256k1.js.map +1 -0
  51. package/lib/esm/signature.d.ts +34 -0
  52. package/lib/esm/signature.js +283 -0
  53. package/lib/esm/signature.js.map +1 -0
  54. package/lib/esm/signer.d.ts +10 -0
  55. package/lib/esm/signer.js +2 -0
  56. package/lib/esm/signer.js.map +1 -0
  57. package/lib/esm/utils.d.ts +4 -0
  58. package/lib/esm/utils.js +10 -0
  59. package/lib/esm/utils.js.map +1 -0
  60. package/lib/esm/x25519.d.ts +38 -0
  61. package/lib/esm/x25519.js +158 -0
  62. package/lib/esm/x25519.js.map +1 -0
  63. package/package.json +55 -0
  64. package/src/bytes.ts +12 -0
  65. package/src/ed25519-sign-browser.ts +43 -0
  66. package/src/ed25519-sign.ts +83 -0
  67. package/src/ed25519.ts +194 -0
  68. package/src/encryption.ts +376 -0
  69. package/src/errors.ts +5 -0
  70. package/src/hash-browser.ts +10 -0
  71. package/src/hash.ts +10 -0
  72. package/src/index.ts +14 -0
  73. package/src/key.ts +80 -0
  74. package/src/keychain.ts +197 -0
  75. package/src/libp2p.ts +27 -0
  76. package/src/prehash.ts +42 -0
  77. package/src/random-browser.ts +2 -0
  78. package/src/random.ts +2 -0
  79. package/src/sepc256k1.ts +229 -0
  80. package/src/signature.ts +284 -0
  81. package/src/signer.ts +18 -0
  82. package/src/utils.ts +15 -0
  83. package/src/x25519.ts +167 -0
@@ -0,0 +1,284 @@
1
+ import {
2
+ deserialize,
3
+ variant,
4
+ field,
5
+ option,
6
+ serialize,
7
+ AbstractType,
8
+ } from "@dao-xyz/borsh";
9
+ import { equals } from "@peerbit/uint8arrays";
10
+ import { verifySignatureEd25519 } from "./ed25519-sign.js";
11
+ import { Ed25519PublicKey } from "./ed25519.js";
12
+ import { PublicSignKey } from "./key.js";
13
+ import { PreHash } from "./prehash.js";
14
+ import { Secp256k1PublicKey, verifySignatureSecp256k1 } from "./sepc256k1.js";
15
+ import { SignWithKey } from "./signer.js";
16
+
17
+ @variant(0)
18
+ export class SignatureWithKey {
19
+ @field({ type: Uint8Array })
20
+ signature: Uint8Array;
21
+
22
+ @field({ type: PublicSignKey })
23
+ publicKey: PublicSignKey;
24
+
25
+ @field({ type: "u8" })
26
+ prehash: PreHash = PreHash.NONE; // 0 no prehash, 1 sha256, 2 blake3?
27
+
28
+ constructor(props: {
29
+ signature: Uint8Array;
30
+ publicKey: PublicSignKey;
31
+ prehash: PreHash;
32
+ }) {
33
+ if (props) {
34
+ this.signature = props.signature;
35
+ this.publicKey = props.publicKey;
36
+ this.prehash = props.prehash;
37
+ }
38
+ }
39
+
40
+ equals(other: SignatureWithKey): boolean {
41
+ if (!equals(this.signature, other.signature)) {
42
+ return false;
43
+ }
44
+ return (
45
+ Buffer.compare(serialize(this.publicKey), serialize(other.publicKey)) ===
46
+ 0 && this.prehash == other.prehash
47
+ );
48
+ }
49
+ }
50
+
51
+ @variant(0)
52
+ export class MaybeSigned<T> {
53
+ @field({ type: Uint8Array })
54
+ data: Uint8Array;
55
+
56
+ @field({ type: option(SignatureWithKey) })
57
+ signature?: SignatureWithKey;
58
+
59
+ constructor(props?: {
60
+ data: Uint8Array;
61
+ value?: T;
62
+ signature?: SignatureWithKey;
63
+ }) {
64
+ if (props) {
65
+ this.data = props.data;
66
+ this.signature = props.signature;
67
+ this._value = props.value;
68
+ }
69
+ }
70
+
71
+ _value?: T;
72
+
73
+ getValue(constructor: AbstractType<T>): T {
74
+ return deserialize(this.data, constructor);
75
+ }
76
+
77
+ async verify(): Promise<boolean> {
78
+ if (!this.signature) {
79
+ return true;
80
+ }
81
+ return verify(this.signature, this.data);
82
+ }
83
+
84
+ equals(other: MaybeSigned<T>): boolean {
85
+ if (!equals(this.data, other.data)) {
86
+ return false;
87
+ }
88
+ if (!this.signature !== !other.signature) {
89
+ return false;
90
+ }
91
+ if (this.signature && other.signature) {
92
+ return this.signature.equals(other.signature);
93
+ }
94
+ return true;
95
+ }
96
+
97
+ /**
98
+ * In place
99
+ * @param signer
100
+ */
101
+ async sign(signer: SignWithKey): Promise<MaybeSigned<T>> {
102
+ const signatureResult = await signer(this.data);
103
+ this.signature = signatureResult;
104
+ return this;
105
+ }
106
+ }
107
+
108
+ export const verify = async (signature: SignatureWithKey, data: Uint8Array) => {
109
+ if (signature.publicKey instanceof Ed25519PublicKey) {
110
+ return verifySignatureEd25519(signature, data);
111
+ } else if (signature.publicKey instanceof Secp256k1PublicKey) {
112
+ return verifySignatureSecp256k1(signature, data);
113
+ }
114
+ return false;
115
+ };
116
+
117
+ /*
118
+
119
+ @variant(0)
120
+ export class SignatureWithKey {
121
+ @field({ type: Uint8Array })
122
+ signature: Uint8Array;
123
+
124
+ @field({ type: PublicSignKey })
125
+ publicKey: PublicSignKey;
126
+
127
+ constructor(props?: { signature: Uint8Array; publicKey: PublicSignKey }) {
128
+ if (props) {
129
+ this.signature = props.signature;
130
+ this.publicKey = props.publicKey;
131
+ }
132
+ }
133
+
134
+ equals(other: SignatureWithKey): boolean {
135
+ if (!equals(this.signature, other.signature)) {
136
+ return false;
137
+ }
138
+ return (
139
+ Buffer.compare(
140
+ serialize(this.publicKey),
141
+ serialize(other.publicKey)
142
+ ) === 0
143
+ );
144
+ }
145
+ }
146
+
147
+ @variant(0)
148
+ export abstract class MaybeSigned<T> {
149
+
150
+ @field({ type: Uint8Array })
151
+ data: Uint8Array;
152
+
153
+ constructor(props: {
154
+ data: Uint8Array;
155
+ value?: T;
156
+ }) {
157
+ this.data = props.data;
158
+ this._value = props.value;
159
+ }
160
+
161
+ _value?: T;
162
+
163
+ getValue(constructor: AbstractType<T>): T {
164
+ return deserialize(this.data, constructor);
165
+ }
166
+
167
+ abstract verify(): Promise<boolean>
168
+
169
+ equals(other: MaybeSigned<T>): boolean {
170
+ if (!equals(this.data, other.data)) {
171
+ return false;
172
+ }
173
+ return true;
174
+ }
175
+
176
+ }
177
+
178
+ @variant(0)
179
+ export class Signed<T> extends MaybeSigned<T> {
180
+
181
+ @field({ type: option(SignatureWithKey) })
182
+ signature: SignatureWithKey;
183
+
184
+ constructor(props: {
185
+ data: Uint8Array;
186
+ value?: T;
187
+ signature: SignatureWithKey;
188
+ }) {
189
+ super(props)
190
+ this.signature = props.signature;
191
+
192
+ }
193
+
194
+ async verify(): Promise<boolean> {
195
+ return verify(
196
+ this.signature.signature,
197
+ this.signature.publicKey,
198
+ this.data
199
+ );
200
+ }
201
+
202
+ equals(other: MaybeSigned<T>): boolean {
203
+ if (other instanceof Signed<T>) {
204
+ if (!this.signature !== !other.signature) {
205
+ return false;
206
+ }
207
+ if (this.signature && other.signature) {
208
+ return this.signature.equals(other.signature);
209
+ }
210
+ return super.equals(other)
211
+ }
212
+ else {
213
+ return false;
214
+ }
215
+ }
216
+
217
+
218
+ async sign(signer: SignWithKey): Promise<MaybeSigned<T>> {
219
+ const signatureResult = await signer(this.data);
220
+ this.signature = new SignatureWithKey({
221
+ publicKey: signatureResult.publicKey,
222
+ signature: signatureResult.signature,
223
+ });
224
+ return this;
225
+ }
226
+ }
227
+
228
+
229
+ @variant(0)
230
+ export class Unsigned<T> extends MaybeSigned<T> {
231
+
232
+
233
+ constructor(props: {
234
+ data: Uint8Array;
235
+ value?: T;
236
+ }) {
237
+ super(props)
238
+ }
239
+
240
+ equals(other: MaybeSigned<T>): boolean {
241
+ if (other instanceof Unsigned) {
242
+ return super.equals(other)
243
+ }
244
+ else {
245
+ return false;
246
+ }
247
+ }
248
+
249
+
250
+ async sign(signer: SignWithKey): Promise<Signed<T>> {
251
+ const signatureResult = await signer(this.data);
252
+ return new Signed({
253
+ data: this.data,
254
+ signature: new SignatureWithKey({
255
+ publicKey: signatureResult.publicKey,
256
+ signature: signatureResult.signature,
257
+ }),
258
+ value: this._value
259
+ });
260
+ }
261
+
262
+ async verify(): Promise<boolean> {
263
+ return true;
264
+ }
265
+ }
266
+
267
+
268
+ export const verify = (
269
+ signature: Uint8Array,
270
+ publicKey: PublicSignKey,
271
+ data: Uint8Array
272
+ ) => {
273
+ if (!signature) {
274
+ return true;
275
+ }
276
+ if (publicKey instanceof Ed25519PublicKey) {
277
+ return verifySignatureEd25519(signature, publicKey, data);
278
+ } else if (publicKey instanceof Secp256k1PublicKey) {
279
+ return verifySignatureSecp256k1(signature, publicKey, data);
280
+ }
281
+ return false;
282
+ };
283
+
284
+ */
package/src/signer.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { PublicSignKey } from "./key.js";
2
+ import { PreHash } from "./prehash.js";
3
+ import { SignatureWithKey } from "./signature.js";
4
+
5
+ export interface Signer {
6
+ sign: (
7
+ bytes: Uint8Array,
8
+ prehash?: PreHash
9
+ ) => Promise<SignatureWithKey> | SignatureWithKey;
10
+ }
11
+
12
+ export type SignWithKey = (
13
+ bytes: Uint8Array
14
+ ) => Promise<SignatureWithKey> | SignatureWithKey;
15
+
16
+ export type Identity<T extends PublicSignKey = PublicSignKey> = Signer & {
17
+ publicKey: T;
18
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,15 @@
1
+ import sodium from "libsodium-wrappers";
2
+ export const fromHexString = (hexString: string) =>
3
+ Uint8Array.from(
4
+ hexString.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
5
+ );
6
+
7
+ export const toHexString = (bytes: Uint8Array) =>
8
+ bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
9
+
10
+ export const toBase64 = (arr: Uint8Array) => {
11
+ return sodium.to_base64(arr, sodium.base64_variants.ORIGINAL);
12
+ };
13
+ export const fromBase64 = (base64: string) => {
14
+ return sodium.from_base64(base64, sodium.base64_variants.ORIGINAL);
15
+ };
package/src/x25519.ts ADDED
@@ -0,0 +1,167 @@
1
+ export * from "./errors.js";
2
+ import { field, fixedArray, variant } from "@dao-xyz/borsh";
3
+ import { compare } from "@peerbit/uint8arrays";
4
+ import sodium from "libsodium-wrappers";
5
+ import {
6
+ Keypair,
7
+ PrivateEncryptionKey,
8
+ PublicKeyEncryptionKey,
9
+ } from "./key.js";
10
+ import {
11
+ Ed25519Keypair,
12
+ Ed25519PublicKey,
13
+ Ed25519PrivateKey,
14
+ } from "./ed25519.js";
15
+ import { toHexString } from "./utils.js";
16
+ import { PeerId } from "@libp2p/interface-peer-id";
17
+ @variant(0)
18
+ export class X25519PublicKey extends PublicKeyEncryptionKey {
19
+ @field({ type: fixedArray("u8", 32) })
20
+ publicKey: Uint8Array;
21
+
22
+ constructor(properties: { publicKey: Uint8Array }) {
23
+ super();
24
+ if (properties.publicKey.length !== 32) {
25
+ throw new Error("Expecting key to have length 32");
26
+ }
27
+ this.publicKey = properties.publicKey;
28
+ }
29
+
30
+ equals(other: PublicKeyEncryptionKey): boolean {
31
+ if (other instanceof X25519PublicKey) {
32
+ return compare(this.publicKey, other.publicKey) === 0;
33
+ }
34
+ return false;
35
+ }
36
+ toString(): string {
37
+ return "x25519p/" + toHexString(this.publicKey);
38
+ }
39
+
40
+ static async from(
41
+ ed25119PublicKey: Ed25519PublicKey
42
+ ): Promise<X25519PublicKey> {
43
+ await sodium.ready;
44
+ return new X25519PublicKey({
45
+ publicKey: sodium.crypto_sign_ed25519_pk_to_curve25519(
46
+ ed25119PublicKey.publicKey
47
+ ),
48
+ });
49
+ }
50
+
51
+ static async fromPeerId(peerId: PeerId): Promise<X25519PublicKey> {
52
+ await sodium.ready;
53
+ const ed = await Ed25519PublicKey.fromPeerId(peerId);
54
+ return X25519PublicKey.from(ed);
55
+ }
56
+
57
+ static async create(): Promise<X25519PublicKey> {
58
+ await sodium.ready;
59
+ return new X25519PublicKey({
60
+ publicKey: sodium.crypto_box_keypair().publicKey,
61
+ });
62
+ }
63
+ }
64
+
65
+ @variant(0)
66
+ export class X25519SecretKey extends PrivateEncryptionKey {
67
+ @field({ type: fixedArray("u8", 32) })
68
+ secretKey: Uint8Array;
69
+
70
+ constructor(properties: { secretKey: Uint8Array }) {
71
+ super();
72
+ if (properties.secretKey.length !== 32) {
73
+ throw new Error("Expecting key to have length 32");
74
+ }
75
+ this.secretKey = properties.secretKey;
76
+ }
77
+
78
+ equals(other: PublicKeyEncryptionKey): boolean {
79
+ if (other instanceof X25519SecretKey) {
80
+ return (
81
+ compare(this.secretKey, (other as X25519SecretKey).secretKey) === 0
82
+ );
83
+ }
84
+ return false;
85
+ }
86
+ toString(): string {
87
+ return "x25519s" + toHexString(this.secretKey);
88
+ }
89
+
90
+ async publicKey(): Promise<X25519PublicKey> {
91
+ return new X25519PublicKey({
92
+ publicKey: sodium.crypto_scalarmult_base(this.secretKey),
93
+ });
94
+ }
95
+ static async from(ed25119Keypair: Ed25519Keypair): Promise<X25519SecretKey> {
96
+ await sodium.ready;
97
+ return new X25519SecretKey({
98
+ secretKey: sodium.crypto_sign_ed25519_sk_to_curve25519(
99
+ ed25119Keypair.privateKeyPublicKey
100
+ ),
101
+ });
102
+ }
103
+
104
+ static async create(): Promise<X25519SecretKey> {
105
+ await sodium.ready;
106
+ return new X25519SecretKey({
107
+ secretKey: sodium.crypto_box_keypair().privateKey,
108
+ });
109
+ }
110
+ }
111
+
112
+ @variant(1)
113
+ export class X25519Keypair extends Keypair {
114
+ @field({ type: X25519PublicKey })
115
+ publicKey: X25519PublicKey;
116
+
117
+ @field({ type: X25519SecretKey })
118
+ secretKey: X25519SecretKey;
119
+
120
+ constructor(properties: {
121
+ publicKey: X25519PublicKey;
122
+ secretKey: X25519SecretKey;
123
+ }) {
124
+ super();
125
+ this.publicKey = properties.publicKey;
126
+ this.secretKey = properties.secretKey;
127
+ }
128
+
129
+ static async create(): Promise<X25519Keypair> {
130
+ await sodium.ready;
131
+ const generated = sodium.crypto_box_keypair();
132
+ const kp = new X25519Keypair({
133
+ publicKey: new X25519PublicKey({
134
+ publicKey: generated.publicKey,
135
+ }),
136
+ secretKey: new X25519SecretKey({
137
+ secretKey: generated.privateKey,
138
+ }),
139
+ });
140
+
141
+ return kp;
142
+ }
143
+
144
+ static async from(ed25119Keypair: Ed25519Keypair): Promise<X25519Keypair> {
145
+ const kp = new X25519Keypair({
146
+ publicKey: await X25519PublicKey.from(ed25119Keypair.publicKey),
147
+ secretKey: await X25519SecretKey.from(ed25119Keypair),
148
+ });
149
+ return kp;
150
+ }
151
+
152
+ static fromPeerId(peerId: PeerId) {
153
+ const ed = Ed25519Keypair.fromPeerId(peerId);
154
+ return X25519Keypair.from(ed);
155
+ }
156
+ equals(other: Keypair) {
157
+ if (other instanceof X25519Keypair) {
158
+ return (
159
+ this.publicKey.equals(other.publicKey) &&
160
+ this.secretKey.equals(
161
+ (other as X25519Keypair).secretKey as X25519SecretKey as any
162
+ )
163
+ );
164
+ }
165
+ return false;
166
+ }
167
+ }