@semaphore-protocol/identity 4.0.0-beta.12 → 4.0.0-beta.13

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/README.md CHANGED
@@ -84,6 +84,28 @@ const { privateKey, publicKey, commitment } = new Identity()
84
84
  const identity = new Identity("your-private-key")
85
85
  ```
86
86
 
87
+ \# **identity.export**(): _string_
88
+
89
+ ```typescript
90
+ import { Identity } from "@semaphore-protocol/identity"
91
+
92
+ const identity = new Identity()
93
+
94
+ const privateKey = identity.export()
95
+ ```
96
+
97
+ \# **identity.import**(privateKey: _string_): _Identity_
98
+
99
+ ```typescript
100
+ import { Identity } from "@semaphore-protocol/identity"
101
+
102
+ const identity = new Identity()
103
+
104
+ const privateKey = identity.export()
105
+
106
+ const identity2 = Identity.import(privateKey)
107
+ ```
108
+
87
109
  \# **identity.signMessage**(message: _BigNumberish_): _Signature\<string>_
88
110
 
89
111
  ```typescript
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @module @semaphore-protocol/identity
3
- * @version 4.0.0-beta.12
3
+ * @version 4.0.0-beta.13
4
4
  * @file A library to create Semaphore identities.
5
5
  * @copyright Ethereum Foundation 2024
6
6
  * @license MIT
@@ -1869,12 +1869,42 @@ getDefaultExportFromCjs(buffer);
1869
1869
 
1870
1870
  /**
1871
1871
  * @module @zk-kit/utils
1872
- * @version 1.0.0-beta.5
1872
+ * @version 1.2.0
1873
1873
  * @file Essential zero-knowledge utility library for JavaScript developers.
1874
1874
  * @copyright Ethereum Foundation 2024
1875
1875
  * @license MIT
1876
1876
  * @see [Github]{@link https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/utils}
1877
1877
  */
1878
+ /**
1879
+ * @module TypeChecks
1880
+ * This module provides utility functions to check data types.
1881
+ * It defines a set of supported types and includes functions to check if
1882
+ * a value is defined and if it matches a supported type. These functions
1883
+ * are useful for type checking and validation in the other libraries,
1884
+ * enhancing code robustness and reliability.
1885
+ */
1886
+ /** @internal */
1887
+ const supportedTypes = [
1888
+ "number",
1889
+ "string",
1890
+ "function",
1891
+ "Array",
1892
+ "Uint8Array",
1893
+ "Buffer",
1894
+ "object",
1895
+ "bigint",
1896
+ "stringified-bigint",
1897
+ "hexadecimal",
1898
+ "bignumber",
1899
+ "bignumberish"
1900
+ ];
1901
+ /**
1902
+ * Returns true if the value is a number, false otherwise.
1903
+ * @param value The value to be checked.
1904
+ */
1905
+ function isNumber(value) {
1906
+ return typeof value === "number";
1907
+ }
1878
1908
  /**
1879
1909
  * Returns true if the value is a string, false otherwise.
1880
1910
  * @param value The value to be checked.
@@ -1882,6 +1912,65 @@ getDefaultExportFromCjs(buffer);
1882
1912
  function isString(value) {
1883
1913
  return typeof value === "string";
1884
1914
  }
1915
+ /**
1916
+ * Returns true if the value is a function, false otherwise.
1917
+ * @param value The value to be checked.
1918
+ */
1919
+ function isFunction(value) {
1920
+ return typeof value === "function";
1921
+ }
1922
+ /**
1923
+ * Returns true if the value is an object, false otherwise.
1924
+ * Please, note that arrays are also objects in JavaScript.
1925
+ * @param value The value to be checked.
1926
+ */
1927
+ function isObject(value) {
1928
+ return typeof value === "object";
1929
+ }
1930
+ /**
1931
+ * Returns true if the value is an Array instance, false otherwise.
1932
+ * @param value The value to be checked.
1933
+ */
1934
+ function isArray(value) {
1935
+ return isObject(value) && Array.isArray(value);
1936
+ }
1937
+ /**
1938
+ * Returns true if the value is a Uint8Array instance, false otherwise.
1939
+ * @param value The value to be checked.
1940
+ */
1941
+ function isUint8Array(value) {
1942
+ return value instanceof Uint8Array;
1943
+ }
1944
+ /**
1945
+ * Returns true if the value is a Buffer instance, false otherwise.
1946
+ * @param value The value to be checked.
1947
+ */
1948
+ function isBuffer(value) {
1949
+ return buffer.Buffer.isBuffer(value);
1950
+ }
1951
+ /**
1952
+ * Returns true if the value is a bigint, false otherwise.
1953
+ * @param value The value to be checked.
1954
+ */
1955
+ function isBigInt(value) {
1956
+ return typeof value === "bigint";
1957
+ }
1958
+ /**
1959
+ * Checks if the given value is a string that represents a valid bigint.
1960
+ * @param value The value to be checked if it's a stringified bigint.
1961
+ */
1962
+ function isStringifiedBigInt(value) {
1963
+ if (!isString(value)) {
1964
+ return false;
1965
+ }
1966
+ try {
1967
+ BigInt(value);
1968
+ return true;
1969
+ }
1970
+ catch {
1971
+ return false;
1972
+ }
1973
+ }
1885
1974
  /**
1886
1975
  * Checks if a string is a valid hexadecimal string representation.
1887
1976
  * If 'prefix' is 'true', the string must start with '0x' or '0X' followed by one or more
@@ -1899,10 +1988,79 @@ function isHexadecimal(value, prefix = true) {
1899
1988
  }
1900
1989
  return /^[0-9a-fA-F]+$/.test(value);
1901
1990
  }
1991
+ /**
1992
+ * Checks if the given value can be considered as BigNumber.
1993
+ * A value is considered a BigNumber if it is a bigint or a string
1994
+ * that can be converted to a bigint (via `Bigint(s)`).
1995
+ * @param value The value to check.
1996
+ */
1997
+ function isBigNumber(value) {
1998
+ return isBigInt(value) || isStringifiedBigInt(value);
1999
+ }
2000
+ /**
2001
+ * Checks if the given value can be considered as BigNumberish.
2002
+ * A value is considered BigNumberish if it meets
2003
+ * any of the following conditions: it's a number, a bigint, a string
2004
+ * that can be converted to a bigint, a hexadecimal
2005
+ * string, or a Buffer object.
2006
+ * @param value The value to check.
2007
+ */
2008
+ function isBigNumberish(value) {
2009
+ return (isNumber(value) ||
2010
+ isBigInt(value) ||
2011
+ isStringifiedBigInt(value) ||
2012
+ isHexadecimal(value) ||
2013
+ isBuffer(value) ||
2014
+ isUint8Array(value));
2015
+ }
2016
+ /**
2017
+ * Returns true if the value type is the same as the type passed
2018
+ * as the second parameter, false otherwise.
2019
+ * @param value
2020
+ * @param type The expected type.
2021
+ */
2022
+ function isType(value, type) {
2023
+ switch (type) {
2024
+ case "number":
2025
+ return isNumber(value);
2026
+ case "string":
2027
+ return isString(value);
2028
+ case "function":
2029
+ return isFunction(value);
2030
+ case "Array":
2031
+ return isArray(value);
2032
+ case "Uint8Array":
2033
+ return isUint8Array(value);
2034
+ case "Buffer":
2035
+ return isBuffer(value);
2036
+ case "object":
2037
+ return isObject(value);
2038
+ case "bigint":
2039
+ return isBigInt(value);
2040
+ case "stringified-bigint":
2041
+ return isStringifiedBigInt(value);
2042
+ case "hexadecimal":
2043
+ return isHexadecimal(value);
2044
+ case "bignumber":
2045
+ return isBigNumber(value);
2046
+ case "bignumberish":
2047
+ return isBigNumberish(value);
2048
+ default:
2049
+ return false;
2050
+ }
2051
+ }
2052
+ /**
2053
+ * Returns true if the type is being supported by this utility
2054
+ * functions, false otherwise.
2055
+ * @param type The type to be checked.
2056
+ */
2057
+ function isSupportedType(type) {
2058
+ return supportedTypes.includes(type);
2059
+ }
1902
2060
 
1903
2061
  /**
1904
2062
  * @module @zk-kit/utils
1905
- * @version 1.0.0-beta.5
2063
+ * @version 1.2.0
1906
2064
  * @file Essential zero-knowledge utility library for JavaScript developers.
1907
2065
  * @copyright Ethereum Foundation 2024
1908
2066
  * @license MIT
@@ -1919,40 +2077,60 @@ function requireString(parameterValue, parameterName) {
1919
2077
  }
1920
2078
  }
1921
2079
  /**
1922
- * @throws Throws a type error if the parameter value is not a hexadecimal string.
1923
- * If 'prefix' is 'true', the string must start with '0x' or '0X' followed by one or more
1924
- * hexadecimal digits (0-9, a-f, A-F), otherwise no prefix is expected. 'prefix' is optional and
1925
- * if its value it is not explicitly defined it will be set to 'true' by default.
2080
+ * @throws Throws a type error if the parameter value type is not part of the list of types.
1926
2081
  * @param parameterValue The parameter value.
1927
2082
  * @param parameterName The parameter name.
1928
- * @param prefix A boolean to include or not a '0x' or '0X' prefix.
1929
2083
  */
1930
- function requireHexadecimal(parameterValue, parameterName, prefix = true) {
1931
- if (!isHexadecimal(parameterValue, prefix)) {
1932
- throw new TypeError(`Parameter '${parameterName}' is not a hexadecimal string`);
2084
+ function requireTypes(parameterValue, parameterName, types) {
2085
+ for (const type of types) {
2086
+ if (!isSupportedType(type)) {
2087
+ throw new Error(`Type '${type}' is not supported`);
2088
+ }
1933
2089
  }
2090
+ for (const type of types) {
2091
+ if (isType(parameterValue, type)) {
2092
+ return;
2093
+ }
2094
+ }
2095
+ throw new TypeError(`Parameter '${parameterName}' is none of the following types: ${types.join(", ")}`);
1934
2096
  }
1935
2097
 
1936
2098
  /**
1937
2099
  * @module @zk-kit/utils
1938
- * @version 1.0.0-beta.5
2100
+ * @version 1.2.0
1939
2101
  * @file Essential zero-knowledge utility library for JavaScript developers.
1940
2102
  * @copyright Ethereum Foundation 2024
1941
2103
  * @license MIT
1942
2104
  * @see [Github]{@link https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/utils}
1943
2105
  */
1944
2106
  /**
1945
- * Converts an hexadecimal string to a buffer. The hexadecimal string
1946
- * should not start with '0x' or '0X'. It keeps the bytes in the same order.
1947
- * @param value The hexadecimal string to convert.
1948
- * @returns The buffer representation of the hexadecimal string.
2107
+ * Converts bytes to a base64 string. It accepts 'Buffer' or 'Uint8Array'.
2108
+ * @param value The bytes to convert.
2109
+ * @returns The converted base64 string.
1949
2110
  */
1950
- function hexadecimalToBuffer(value) {
1951
- requireHexadecimal(value, "value", false);
1952
- if (value.length % 2 !== 0) {
1953
- value = `0${value}`;
1954
- }
1955
- return buffer.Buffer.from(value, "hex");
2111
+ function bufferToBase64(value) {
2112
+ requireTypes(value, "value", ["Buffer", "Uint8Array"]);
2113
+ return buffer.Buffer.from(value).toString("base64");
2114
+ }
2115
+ /**
2116
+ * Converts a base64 string to bytes (i.e. a buffer). This function does not check
2117
+ * if the input value is a valid base64 string. If there are unsupported characters
2118
+ * they will be ignored.
2119
+ * @param value The base64 string to convert.
2120
+ * @returns The converted buffer.
2121
+ */
2122
+ function base64ToBuffer(value) {
2123
+ requireString(value, "value");
2124
+ return buffer.Buffer.from(value, "base64");
2125
+ }
2126
+ /**
2127
+ * Converts text (utf8) to a base64 string.
2128
+ * @param value The text to convert.
2129
+ * @returns The converted base64 string.
2130
+ */
2131
+ function textToBase64(value) {
2132
+ requireString(value, "value");
2133
+ return buffer.Buffer.from(value, "utf8").toString("base64");
1956
2134
  }
1957
2135
 
1958
2136
  var poseidon2$1 = {};
@@ -2059,14 +2237,12 @@ function poseidon2(inputs) {
2059
2237
  * and {@link https://www.poseidon-hash.info | Poseidon} for signatures.
2060
2238
  * In addition, the commitment, i.e. the hash of the public key, is used to represent
2061
2239
  * Semaphore identities in groups, adding an additional layer of privacy and security.
2062
- * The private key of the identity is stored as a hexadecimal string or text.
2063
- * The other attributes are stored as stringified bigint.
2240
+ * The private key of the identity can be exported as a base64 string.
2064
2241
  */
2065
2242
  class Identity {
2066
2243
  /**
2067
- * Initializes the class attributes based on a given private key, which must be a hexadecimal string or a text.
2068
- * Hexadecimal strings must not start with '0x' or '0X'.
2069
- * If the private key is not passed as a parameter, a random hexadecimal key will be generated.
2244
+ * Initializes the class attributes based on a given private key, which must be text or a buffer.
2245
+ * If the private key is not passed as a parameter, a random private key will be generated.
2070
2246
  * The EdDSAPoseidon class is used to generate the secret scalar and the public key.
2071
2247
  * Additionally, the constructor computes a commitment of the public key using a hash function (Poseidon).
2072
2248
  *
@@ -2080,28 +2256,15 @@ class Identity {
2080
2256
  * @param privateKey The private key used to derive the public key (hexadecimal or string).
2081
2257
  */
2082
2258
  constructor(privateKey) {
2083
- let eddsa;
2084
- if (privateKey) {
2085
- requireString(privateKey, "privateKey");
2086
- this._privateKey = privateKey;
2087
- if (isHexadecimal(privateKey, false)) {
2088
- eddsa = new eddsaPoseidon.EdDSAPoseidon(hexadecimalToBuffer(privateKey));
2089
- }
2090
- else {
2091
- eddsa = new eddsaPoseidon.EdDSAPoseidon(privateKey);
2092
- }
2093
- }
2094
- else {
2095
- eddsa = new eddsaPoseidon.EdDSAPoseidon();
2096
- this._privateKey = eddsa.privateKey;
2097
- }
2259
+ const eddsa = new eddsaPoseidon.EdDSAPoseidon(privateKey);
2260
+ this._privateKey = eddsa.privateKey;
2098
2261
  this._secretScalar = eddsa.secretScalar;
2099
2262
  this._publicKey = eddsa.publicKey;
2100
2263
  this._commitment = poseidon2_2(this._publicKey);
2101
2264
  }
2102
2265
  /**
2103
2266
  * Returns the private key.
2104
- * @returns The private key as a string (hexadecimal or text).
2267
+ * @returns The private key as a buffer or text.
2105
2268
  */
2106
2269
  get privateKey() {
2107
2270
  return this._privateKey;
@@ -2127,6 +2290,25 @@ class Identity {
2127
2290
  get commitment() {
2128
2291
  return this._commitment;
2129
2292
  }
2293
+ /**
2294
+ * Returns the private key encoded as a base64 string.
2295
+ * @returns The private key as a base64 string.
2296
+ */
2297
+ export() {
2298
+ if (isString(this._privateKey)) {
2299
+ return textToBase64(this._privateKey);
2300
+ }
2301
+ return bufferToBase64(this.privateKey);
2302
+ }
2303
+ /**
2304
+ * Returns a Semaphore identity based on a private key encoded as a base64 string.
2305
+ * The private key will be converted to a buffer, regardless of its original type.
2306
+ * @param privateKey The private key as a base64 string.
2307
+ * @returns The Semaphore identity.
2308
+ */
2309
+ static import(privateKey) {
2310
+ return new Identity(base64ToBuffer(privateKey));
2311
+ }
2130
2312
  /**
2131
2313
  * Generates a signature for a given message using the private key.
2132
2314
  * This method demonstrates how to sign a message and could be used
@@ -2140,10 +2322,7 @@ class Identity {
2140
2322
  * @returns A {@link https://zkkit.pse.dev/types/_zk_kit_eddsa_poseidon.Signature.html | Signature} object containing the signature components.
2141
2323
  */
2142
2324
  signMessage(message) {
2143
- const privateKey = isHexadecimal(this.privateKey, false)
2144
- ? hexadecimalToBuffer(this.privateKey)
2145
- : this.privateKey;
2146
- return eddsaPoseidon.signMessage(privateKey, message);
2325
+ return eddsaPoseidon.signMessage(this.privateKey, message);
2147
2326
  }
2148
2327
  /**
2149
2328
  * Verifies a signature against a given message and public key.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @module @semaphore-protocol/identity
3
- * @version 4.0.0-beta.12
3
+ * @version 4.0.0-beta.13
4
4
  * @file A library to create Semaphore identities.
5
5
  * @copyright Ethereum Foundation 2024
6
6
  * @license MIT
@@ -1867,12 +1867,42 @@ getDefaultExportFromCjs(buffer);
1867
1867
 
1868
1868
  /**
1869
1869
  * @module @zk-kit/utils
1870
- * @version 1.0.0-beta.5
1870
+ * @version 1.2.0
1871
1871
  * @file Essential zero-knowledge utility library for JavaScript developers.
1872
1872
  * @copyright Ethereum Foundation 2024
1873
1873
  * @license MIT
1874
1874
  * @see [Github]{@link https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/utils}
1875
1875
  */
1876
+ /**
1877
+ * @module TypeChecks
1878
+ * This module provides utility functions to check data types.
1879
+ * It defines a set of supported types and includes functions to check if
1880
+ * a value is defined and if it matches a supported type. These functions
1881
+ * are useful for type checking and validation in the other libraries,
1882
+ * enhancing code robustness and reliability.
1883
+ */
1884
+ /** @internal */
1885
+ const supportedTypes = [
1886
+ "number",
1887
+ "string",
1888
+ "function",
1889
+ "Array",
1890
+ "Uint8Array",
1891
+ "Buffer",
1892
+ "object",
1893
+ "bigint",
1894
+ "stringified-bigint",
1895
+ "hexadecimal",
1896
+ "bignumber",
1897
+ "bignumberish"
1898
+ ];
1899
+ /**
1900
+ * Returns true if the value is a number, false otherwise.
1901
+ * @param value The value to be checked.
1902
+ */
1903
+ function isNumber(value) {
1904
+ return typeof value === "number";
1905
+ }
1876
1906
  /**
1877
1907
  * Returns true if the value is a string, false otherwise.
1878
1908
  * @param value The value to be checked.
@@ -1880,6 +1910,65 @@ getDefaultExportFromCjs(buffer);
1880
1910
  function isString(value) {
1881
1911
  return typeof value === "string";
1882
1912
  }
1913
+ /**
1914
+ * Returns true if the value is a function, false otherwise.
1915
+ * @param value The value to be checked.
1916
+ */
1917
+ function isFunction(value) {
1918
+ return typeof value === "function";
1919
+ }
1920
+ /**
1921
+ * Returns true if the value is an object, false otherwise.
1922
+ * Please, note that arrays are also objects in JavaScript.
1923
+ * @param value The value to be checked.
1924
+ */
1925
+ function isObject(value) {
1926
+ return typeof value === "object";
1927
+ }
1928
+ /**
1929
+ * Returns true if the value is an Array instance, false otherwise.
1930
+ * @param value The value to be checked.
1931
+ */
1932
+ function isArray(value) {
1933
+ return isObject(value) && Array.isArray(value);
1934
+ }
1935
+ /**
1936
+ * Returns true if the value is a Uint8Array instance, false otherwise.
1937
+ * @param value The value to be checked.
1938
+ */
1939
+ function isUint8Array(value) {
1940
+ return value instanceof Uint8Array;
1941
+ }
1942
+ /**
1943
+ * Returns true if the value is a Buffer instance, false otherwise.
1944
+ * @param value The value to be checked.
1945
+ */
1946
+ function isBuffer(value) {
1947
+ return buffer.Buffer.isBuffer(value);
1948
+ }
1949
+ /**
1950
+ * Returns true if the value is a bigint, false otherwise.
1951
+ * @param value The value to be checked.
1952
+ */
1953
+ function isBigInt(value) {
1954
+ return typeof value === "bigint";
1955
+ }
1956
+ /**
1957
+ * Checks if the given value is a string that represents a valid bigint.
1958
+ * @param value The value to be checked if it's a stringified bigint.
1959
+ */
1960
+ function isStringifiedBigInt(value) {
1961
+ if (!isString(value)) {
1962
+ return false;
1963
+ }
1964
+ try {
1965
+ BigInt(value);
1966
+ return true;
1967
+ }
1968
+ catch {
1969
+ return false;
1970
+ }
1971
+ }
1883
1972
  /**
1884
1973
  * Checks if a string is a valid hexadecimal string representation.
1885
1974
  * If 'prefix' is 'true', the string must start with '0x' or '0X' followed by one or more
@@ -1897,10 +1986,79 @@ function isHexadecimal(value, prefix = true) {
1897
1986
  }
1898
1987
  return /^[0-9a-fA-F]+$/.test(value);
1899
1988
  }
1989
+ /**
1990
+ * Checks if the given value can be considered as BigNumber.
1991
+ * A value is considered a BigNumber if it is a bigint or a string
1992
+ * that can be converted to a bigint (via `Bigint(s)`).
1993
+ * @param value The value to check.
1994
+ */
1995
+ function isBigNumber(value) {
1996
+ return isBigInt(value) || isStringifiedBigInt(value);
1997
+ }
1998
+ /**
1999
+ * Checks if the given value can be considered as BigNumberish.
2000
+ * A value is considered BigNumberish if it meets
2001
+ * any of the following conditions: it's a number, a bigint, a string
2002
+ * that can be converted to a bigint, a hexadecimal
2003
+ * string, or a Buffer object.
2004
+ * @param value The value to check.
2005
+ */
2006
+ function isBigNumberish(value) {
2007
+ return (isNumber(value) ||
2008
+ isBigInt(value) ||
2009
+ isStringifiedBigInt(value) ||
2010
+ isHexadecimal(value) ||
2011
+ isBuffer(value) ||
2012
+ isUint8Array(value));
2013
+ }
2014
+ /**
2015
+ * Returns true if the value type is the same as the type passed
2016
+ * as the second parameter, false otherwise.
2017
+ * @param value
2018
+ * @param type The expected type.
2019
+ */
2020
+ function isType(value, type) {
2021
+ switch (type) {
2022
+ case "number":
2023
+ return isNumber(value);
2024
+ case "string":
2025
+ return isString(value);
2026
+ case "function":
2027
+ return isFunction(value);
2028
+ case "Array":
2029
+ return isArray(value);
2030
+ case "Uint8Array":
2031
+ return isUint8Array(value);
2032
+ case "Buffer":
2033
+ return isBuffer(value);
2034
+ case "object":
2035
+ return isObject(value);
2036
+ case "bigint":
2037
+ return isBigInt(value);
2038
+ case "stringified-bigint":
2039
+ return isStringifiedBigInt(value);
2040
+ case "hexadecimal":
2041
+ return isHexadecimal(value);
2042
+ case "bignumber":
2043
+ return isBigNumber(value);
2044
+ case "bignumberish":
2045
+ return isBigNumberish(value);
2046
+ default:
2047
+ return false;
2048
+ }
2049
+ }
2050
+ /**
2051
+ * Returns true if the type is being supported by this utility
2052
+ * functions, false otherwise.
2053
+ * @param type The type to be checked.
2054
+ */
2055
+ function isSupportedType(type) {
2056
+ return supportedTypes.includes(type);
2057
+ }
1900
2058
 
1901
2059
  /**
1902
2060
  * @module @zk-kit/utils
1903
- * @version 1.0.0-beta.5
2061
+ * @version 1.2.0
1904
2062
  * @file Essential zero-knowledge utility library for JavaScript developers.
1905
2063
  * @copyright Ethereum Foundation 2024
1906
2064
  * @license MIT
@@ -1917,40 +2075,60 @@ function requireString(parameterValue, parameterName) {
1917
2075
  }
1918
2076
  }
1919
2077
  /**
1920
- * @throws Throws a type error if the parameter value is not a hexadecimal string.
1921
- * If 'prefix' is 'true', the string must start with '0x' or '0X' followed by one or more
1922
- * hexadecimal digits (0-9, a-f, A-F), otherwise no prefix is expected. 'prefix' is optional and
1923
- * if its value it is not explicitly defined it will be set to 'true' by default.
2078
+ * @throws Throws a type error if the parameter value type is not part of the list of types.
1924
2079
  * @param parameterValue The parameter value.
1925
2080
  * @param parameterName The parameter name.
1926
- * @param prefix A boolean to include or not a '0x' or '0X' prefix.
1927
2081
  */
1928
- function requireHexadecimal(parameterValue, parameterName, prefix = true) {
1929
- if (!isHexadecimal(parameterValue, prefix)) {
1930
- throw new TypeError(`Parameter '${parameterName}' is not a hexadecimal string`);
2082
+ function requireTypes(parameterValue, parameterName, types) {
2083
+ for (const type of types) {
2084
+ if (!isSupportedType(type)) {
2085
+ throw new Error(`Type '${type}' is not supported`);
2086
+ }
1931
2087
  }
2088
+ for (const type of types) {
2089
+ if (isType(parameterValue, type)) {
2090
+ return;
2091
+ }
2092
+ }
2093
+ throw new TypeError(`Parameter '${parameterName}' is none of the following types: ${types.join(", ")}`);
1932
2094
  }
1933
2095
 
1934
2096
  /**
1935
2097
  * @module @zk-kit/utils
1936
- * @version 1.0.0-beta.5
2098
+ * @version 1.2.0
1937
2099
  * @file Essential zero-knowledge utility library for JavaScript developers.
1938
2100
  * @copyright Ethereum Foundation 2024
1939
2101
  * @license MIT
1940
2102
  * @see [Github]{@link https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/utils}
1941
2103
  */
1942
2104
  /**
1943
- * Converts an hexadecimal string to a buffer. The hexadecimal string
1944
- * should not start with '0x' or '0X'. It keeps the bytes in the same order.
1945
- * @param value The hexadecimal string to convert.
1946
- * @returns The buffer representation of the hexadecimal string.
2105
+ * Converts bytes to a base64 string. It accepts 'Buffer' or 'Uint8Array'.
2106
+ * @param value The bytes to convert.
2107
+ * @returns The converted base64 string.
1947
2108
  */
1948
- function hexadecimalToBuffer(value) {
1949
- requireHexadecimal(value, "value", false);
1950
- if (value.length % 2 !== 0) {
1951
- value = `0${value}`;
1952
- }
1953
- return buffer.Buffer.from(value, "hex");
2109
+ function bufferToBase64(value) {
2110
+ requireTypes(value, "value", ["Buffer", "Uint8Array"]);
2111
+ return buffer.Buffer.from(value).toString("base64");
2112
+ }
2113
+ /**
2114
+ * Converts a base64 string to bytes (i.e. a buffer). This function does not check
2115
+ * if the input value is a valid base64 string. If there are unsupported characters
2116
+ * they will be ignored.
2117
+ * @param value The base64 string to convert.
2118
+ * @returns The converted buffer.
2119
+ */
2120
+ function base64ToBuffer(value) {
2121
+ requireString(value, "value");
2122
+ return buffer.Buffer.from(value, "base64");
2123
+ }
2124
+ /**
2125
+ * Converts text (utf8) to a base64 string.
2126
+ * @param value The text to convert.
2127
+ * @returns The converted base64 string.
2128
+ */
2129
+ function textToBase64(value) {
2130
+ requireString(value, "value");
2131
+ return buffer.Buffer.from(value, "utf8").toString("base64");
1954
2132
  }
1955
2133
 
1956
2134
  var poseidon2$1 = {};
@@ -2057,14 +2235,12 @@ function poseidon2(inputs) {
2057
2235
  * and {@link https://www.poseidon-hash.info | Poseidon} for signatures.
2058
2236
  * In addition, the commitment, i.e. the hash of the public key, is used to represent
2059
2237
  * Semaphore identities in groups, adding an additional layer of privacy and security.
2060
- * The private key of the identity is stored as a hexadecimal string or text.
2061
- * The other attributes are stored as stringified bigint.
2238
+ * The private key of the identity can be exported as a base64 string.
2062
2239
  */
2063
2240
  class Identity {
2064
2241
  /**
2065
- * Initializes the class attributes based on a given private key, which must be a hexadecimal string or a text.
2066
- * Hexadecimal strings must not start with '0x' or '0X'.
2067
- * If the private key is not passed as a parameter, a random hexadecimal key will be generated.
2242
+ * Initializes the class attributes based on a given private key, which must be text or a buffer.
2243
+ * If the private key is not passed as a parameter, a random private key will be generated.
2068
2244
  * The EdDSAPoseidon class is used to generate the secret scalar and the public key.
2069
2245
  * Additionally, the constructor computes a commitment of the public key using a hash function (Poseidon).
2070
2246
  *
@@ -2078,28 +2254,15 @@ class Identity {
2078
2254
  * @param privateKey The private key used to derive the public key (hexadecimal or string).
2079
2255
  */
2080
2256
  constructor(privateKey) {
2081
- let eddsa;
2082
- if (privateKey) {
2083
- requireString(privateKey, "privateKey");
2084
- this._privateKey = privateKey;
2085
- if (isHexadecimal(privateKey, false)) {
2086
- eddsa = new EdDSAPoseidon(hexadecimalToBuffer(privateKey));
2087
- }
2088
- else {
2089
- eddsa = new EdDSAPoseidon(privateKey);
2090
- }
2091
- }
2092
- else {
2093
- eddsa = new EdDSAPoseidon();
2094
- this._privateKey = eddsa.privateKey;
2095
- }
2257
+ const eddsa = new EdDSAPoseidon(privateKey);
2258
+ this._privateKey = eddsa.privateKey;
2096
2259
  this._secretScalar = eddsa.secretScalar;
2097
2260
  this._publicKey = eddsa.publicKey;
2098
2261
  this._commitment = poseidon2_2(this._publicKey);
2099
2262
  }
2100
2263
  /**
2101
2264
  * Returns the private key.
2102
- * @returns The private key as a string (hexadecimal or text).
2265
+ * @returns The private key as a buffer or text.
2103
2266
  */
2104
2267
  get privateKey() {
2105
2268
  return this._privateKey;
@@ -2125,6 +2288,25 @@ class Identity {
2125
2288
  get commitment() {
2126
2289
  return this._commitment;
2127
2290
  }
2291
+ /**
2292
+ * Returns the private key encoded as a base64 string.
2293
+ * @returns The private key as a base64 string.
2294
+ */
2295
+ export() {
2296
+ if (isString(this._privateKey)) {
2297
+ return textToBase64(this._privateKey);
2298
+ }
2299
+ return bufferToBase64(this.privateKey);
2300
+ }
2301
+ /**
2302
+ * Returns a Semaphore identity based on a private key encoded as a base64 string.
2303
+ * The private key will be converted to a buffer, regardless of its original type.
2304
+ * @param privateKey The private key as a base64 string.
2305
+ * @returns The Semaphore identity.
2306
+ */
2307
+ static import(privateKey) {
2308
+ return new Identity(base64ToBuffer(privateKey));
2309
+ }
2128
2310
  /**
2129
2311
  * Generates a signature for a given message using the private key.
2130
2312
  * This method demonstrates how to sign a message and could be used
@@ -2138,10 +2320,7 @@ class Identity {
2138
2320
  * @returns A {@link https://zkkit.pse.dev/types/_zk_kit_eddsa_poseidon.Signature.html | Signature} object containing the signature components.
2139
2321
  */
2140
2322
  signMessage(message) {
2141
- const privateKey = isHexadecimal(this.privateKey, false)
2142
- ? hexadecimalToBuffer(this.privateKey)
2143
- : this.privateKey;
2144
- return signMessage(privateKey, message);
2323
+ return signMessage(this.privateKey, message);
2145
2324
  }
2146
2325
  /**
2147
2326
  * Verifies a signature against a given message and public key.
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { Point } from "@zk-kit/baby-jubjub";
2
3
  import { Signature } from "@zk-kit/eddsa-poseidon";
3
4
  import type { BigNumberish } from "@zk-kit/utils";
@@ -8,8 +9,7 @@ import type { BigNumberish } from "@zk-kit/utils";
8
9
  * and {@link https://www.poseidon-hash.info | Poseidon} for signatures.
9
10
  * In addition, the commitment, i.e. the hash of the public key, is used to represent
10
11
  * Semaphore identities in groups, adding an additional layer of privacy and security.
11
- * The private key of the identity is stored as a hexadecimal string or text.
12
- * The other attributes are stored as stringified bigint.
12
+ * The private key of the identity can be exported as a base64 string.
13
13
  */
14
14
  export declare class Identity {
15
15
  private _privateKey;
@@ -17,9 +17,8 @@ export declare class Identity {
17
17
  private _publicKey;
18
18
  private _commitment;
19
19
  /**
20
- * Initializes the class attributes based on a given private key, which must be a hexadecimal string or a text.
21
- * Hexadecimal strings must not start with '0x' or '0X'.
22
- * If the private key is not passed as a parameter, a random hexadecimal key will be generated.
20
+ * Initializes the class attributes based on a given private key, which must be text or a buffer.
21
+ * If the private key is not passed as a parameter, a random private key will be generated.
23
22
  * The EdDSAPoseidon class is used to generate the secret scalar and the public key.
24
23
  * Additionally, the constructor computes a commitment of the public key using a hash function (Poseidon).
25
24
  *
@@ -32,12 +31,12 @@ export declare class Identity {
32
31
  *
33
32
  * @param privateKey The private key used to derive the public key (hexadecimal or string).
34
33
  */
35
- constructor(privateKey?: string);
34
+ constructor(privateKey?: string | Buffer | Uint8Array);
36
35
  /**
37
36
  * Returns the private key.
38
- * @returns The private key as a string (hexadecimal or text).
37
+ * @returns The private key as a buffer or text.
39
38
  */
40
- get privateKey(): string;
39
+ get privateKey(): string | Buffer | Uint8Array;
41
40
  /**
42
41
  * Returns the secret scalar.
43
42
  * @returns The secret scalar as a string.
@@ -53,6 +52,18 @@ export declare class Identity {
53
52
  * @returns The commitment as a string.
54
53
  */
55
54
  get commitment(): bigint;
55
+ /**
56
+ * Returns the private key encoded as a base64 string.
57
+ * @returns The private key as a base64 string.
58
+ */
59
+ export(): string;
60
+ /**
61
+ * Returns a Semaphore identity based on a private key encoded as a base64 string.
62
+ * The private key will be converted to a buffer, regardless of its original type.
63
+ * @param privateKey The private key as a base64 string.
64
+ * @returns The Semaphore identity.
65
+ */
66
+ static import(privateKey: string): Identity;
56
67
  /**
57
68
  * Generates a signature for a given message using the private key.
58
69
  * This method demonstrates how to sign a message and could be used
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semaphore-protocol/identity",
3
- "version": "4.0.0-beta.12",
3
+ "version": "4.0.0-beta.13",
4
4
  "description": "A library to create Semaphore identities.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,8 +40,8 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@zk-kit/baby-jubjub": "1.0.1",
43
- "@zk-kit/eddsa-poseidon": "1.0.1",
44
- "@zk-kit/utils": "1.0.0",
43
+ "@zk-kit/eddsa-poseidon": "1.0.2",
44
+ "@zk-kit/utils": "1.2.0",
45
45
  "poseidon-lite": "0.2.0"
46
46
  }
47
47
  }
package/src/index.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import type { Point } from "@zk-kit/baby-jubjub"
2
2
  import { EdDSAPoseidon, Signature, signMessage, verifySignature } from "@zk-kit/eddsa-poseidon"
3
3
  import type { BigNumberish } from "@zk-kit/utils"
4
- import { hexadecimalToBuffer } from "@zk-kit/utils/conversions"
5
- import { requireString } from "@zk-kit/utils/error-handlers"
6
- import { isHexadecimal } from "@zk-kit/utils/type-checks"
4
+ import { base64ToBuffer, bufferToBase64, textToBase64 } from "@zk-kit/utils/conversions"
5
+ import { isString } from "@zk-kit/utils/type-checks"
7
6
  import { poseidon2 } from "poseidon-lite/poseidon2"
8
7
 
9
8
  /**
@@ -13,12 +12,11 @@ import { poseidon2 } from "poseidon-lite/poseidon2"
13
12
  * and {@link https://www.poseidon-hash.info | Poseidon} for signatures.
14
13
  * In addition, the commitment, i.e. the hash of the public key, is used to represent
15
14
  * Semaphore identities in groups, adding an additional layer of privacy and security.
16
- * The private key of the identity is stored as a hexadecimal string or text.
17
- * The other attributes are stored as stringified bigint.
15
+ * The private key of the identity can be exported as a base64 string.
18
16
  */
19
17
  export class Identity {
20
18
  // The EdDSA private key, passed as a parameter or generated randomly.
21
- private _privateKey: string
19
+ private _privateKey: string | Buffer | Uint8Array
22
20
  // The secret scalar derived from the private key.
23
21
  // It is used in circuits to derive the public key.
24
22
  private _secretScalar: bigint
@@ -28,9 +26,8 @@ export class Identity {
28
26
  private _commitment: bigint
29
27
 
30
28
  /**
31
- * Initializes the class attributes based on a given private key, which must be a hexadecimal string or a text.
32
- * Hexadecimal strings must not start with '0x' or '0X'.
33
- * If the private key is not passed as a parameter, a random hexadecimal key will be generated.
29
+ * Initializes the class attributes based on a given private key, which must be text or a buffer.
30
+ * If the private key is not passed as a parameter, a random private key will be generated.
34
31
  * The EdDSAPoseidon class is used to generate the secret scalar and the public key.
35
32
  * Additionally, the constructor computes a commitment of the public key using a hash function (Poseidon).
36
33
  *
@@ -43,25 +40,10 @@ export class Identity {
43
40
  *
44
41
  * @param privateKey The private key used to derive the public key (hexadecimal or string).
45
42
  */
46
- constructor(privateKey?: string) {
47
- let eddsa: EdDSAPoseidon
48
-
49
- if (privateKey) {
50
- requireString(privateKey, "privateKey")
51
-
52
- this._privateKey = privateKey
53
-
54
- if (isHexadecimal(privateKey, false)) {
55
- eddsa = new EdDSAPoseidon(hexadecimalToBuffer(privateKey))
56
- } else {
57
- eddsa = new EdDSAPoseidon(privateKey)
58
- }
59
- } else {
60
- eddsa = new EdDSAPoseidon()
61
-
62
- this._privateKey = eddsa.privateKey as string
63
- }
43
+ constructor(privateKey?: string | Buffer | Uint8Array) {
44
+ const eddsa = new EdDSAPoseidon(privateKey)
64
45
 
46
+ this._privateKey = eddsa.privateKey
65
47
  this._secretScalar = eddsa.secretScalar
66
48
  this._publicKey = eddsa.publicKey
67
49
  this._commitment = poseidon2(this._publicKey)
@@ -69,9 +51,9 @@ export class Identity {
69
51
 
70
52
  /**
71
53
  * Returns the private key.
72
- * @returns The private key as a string (hexadecimal or text).
54
+ * @returns The private key as a buffer or text.
73
55
  */
74
- public get privateKey(): string {
56
+ public get privateKey(): string | Buffer | Uint8Array {
75
57
  return this._privateKey
76
58
  }
77
59
 
@@ -99,6 +81,28 @@ export class Identity {
99
81
  return this._commitment
100
82
  }
101
83
 
84
+ /**
85
+ * Returns the private key encoded as a base64 string.
86
+ * @returns The private key as a base64 string.
87
+ */
88
+ public export(): string {
89
+ if (isString(this._privateKey)) {
90
+ return textToBase64(this._privateKey as string)
91
+ }
92
+
93
+ return bufferToBase64(this.privateKey as Buffer | Uint8Array)
94
+ }
95
+
96
+ /**
97
+ * Returns a Semaphore identity based on a private key encoded as a base64 string.
98
+ * The private key will be converted to a buffer, regardless of its original type.
99
+ * @param privateKey The private key as a base64 string.
100
+ * @returns The Semaphore identity.
101
+ */
102
+ static import(privateKey: string): Identity {
103
+ return new Identity(base64ToBuffer(privateKey))
104
+ }
105
+
102
106
  /**
103
107
  * Generates a signature for a given message using the private key.
104
108
  * This method demonstrates how to sign a message and could be used
@@ -112,11 +116,7 @@ export class Identity {
112
116
  * @returns A {@link https://zkkit.pse.dev/types/_zk_kit_eddsa_poseidon.Signature.html | Signature} object containing the signature components.
113
117
  */
114
118
  public signMessage(message: BigNumberish): Signature<bigint> {
115
- const privateKey = isHexadecimal(this.privateKey, false)
116
- ? hexadecimalToBuffer(this.privateKey)
117
- : this.privateKey
118
-
119
- return signMessage(privateKey, message)
119
+ return signMessage(this.privateKey, message)
120
120
  }
121
121
 
122
122
  /**