@@ -5,19 +5,23 @@ use blake2::Digest as DigestTrait;
5
5
6
6
type Blake2b256 = blake2:: Blake2b < blake2:: digest:: consts:: U32 > ;
7
7
8
+ /// A Blake2b256 Hasher
8
9
#[ derive( Debug , Default ) ]
9
10
pub struct Hasher ( Blake2b256 ) ;
10
11
11
12
impl Hasher {
13
+ /// Initialize a new Blake2b256 Hasher instance.
12
14
pub fn new ( ) -> Self {
13
15
Self ( Blake2b256 :: new ( ) )
14
16
}
15
17
18
+ /// Process the provided data, updating internal state.
16
19
pub fn update < T : AsRef < [ u8 ] > > ( & mut self , data : T ) {
17
20
self . 0 . update ( data)
18
21
}
19
22
20
- /// Retrieve result and consume hasher instance.
23
+ /// Finalize hashing, consuming the Hasher instance and returning the resultant hash or
24
+ /// `Digest`.
21
25
pub fn finalize ( self ) -> Digest {
22
26
let mut buf = [ 0 ; Digest :: LENGTH ] ;
23
27
let result = self . 0 . finalize ( ) ;
@@ -27,6 +31,8 @@ impl Hasher {
27
31
Digest :: new ( buf)
28
32
}
29
33
34
+ /// Convenience function for creating a new Hasher instance, hashing the provided data, and
35
+ /// returning the resultant `Digest`
30
36
pub fn digest < T : AsRef < [ u8 ] > > ( data : T ) -> Digest {
31
37
let mut hasher = Self :: new ( ) ;
32
38
hasher. update ( data) ;
@@ -45,6 +51,28 @@ impl std::io::Write for Hasher {
45
51
}
46
52
47
53
impl crate :: Ed25519PublicKey {
54
+ /// Derive an `Address` from this Public Key
55
+ ///
56
+ /// An `Address` can be derived from an `Ed25519PublicKey` by hashing the bytes of the public
57
+ /// key prefixed with the Ed25519 `SignatureScheme` flag (`0x00`).
58
+ ///
59
+ /// `hash( 0x00 || 32-byte ed25519 public key)`
60
+ ///
61
+ /// ```
62
+ /// use sui_sdk_types::hash::Hasher;
63
+ /// use sui_sdk_types::Address;
64
+ /// use sui_sdk_types::Ed25519PublicKey;
65
+ ///
66
+ /// let public_key_bytes = [0; 32];
67
+ /// let mut hasher = Hasher::new();
68
+ /// hasher.update([0x00]); // The SignatureScheme flag for Ed25519 is `0`
69
+ /// hasher.update(public_key_bytes);
70
+ /// let address = Address::new(hasher.finalize().into_inner());
71
+ /// println!("Address: {}", address);
72
+ ///
73
+ /// let public_key = Ed25519PublicKey::new(public_key_bytes);
74
+ /// assert_eq!(address, public_key.derive_address());
75
+ /// ```
48
76
pub fn derive_address ( & self ) -> Address {
49
77
let mut hasher = Hasher :: new ( ) ;
50
78
self . write_into_hasher ( & mut hasher) ;
@@ -59,6 +87,28 @@ impl crate::Ed25519PublicKey {
59
87
}
60
88
61
89
impl crate :: Secp256k1PublicKey {
90
+ /// Derive an `Address` from this Public Key
91
+ ///
92
+ /// An `Address` can be derived from a `Secp256k1PublicKey` by hashing the bytes of the public
93
+ /// key prefixed with the Secp256k1 `SignatureScheme` flag (`0x01`).
94
+ ///
95
+ /// `hash( 0x01 || 33-byte secp256k1 public key)`
96
+ ///
97
+ /// ```
98
+ /// use sui_sdk_types::hash::Hasher;
99
+ /// use sui_sdk_types::Address;
100
+ /// use sui_sdk_types::Secp256k1PublicKey;
101
+ ///
102
+ /// let public_key_bytes = [0; 33];
103
+ /// let mut hasher = Hasher::new();
104
+ /// hasher.update([0x01]); // The SignatureScheme flag for Secp256k1 is `1`
105
+ /// hasher.update(public_key_bytes);
106
+ /// let address = Address::new(hasher.finalize().into_inner());
107
+ /// println!("Address: {}", address);
108
+ ///
109
+ /// let public_key = Secp256k1PublicKey::new(public_key_bytes);
110
+ /// assert_eq!(address, public_key.derive_address());
111
+ /// ```
62
112
pub fn derive_address ( & self ) -> Address {
63
113
let mut hasher = Hasher :: new ( ) ;
64
114
self . write_into_hasher ( & mut hasher) ;
@@ -73,6 +123,28 @@ impl crate::Secp256k1PublicKey {
73
123
}
74
124
75
125
impl crate :: Secp256r1PublicKey {
126
+ /// Derive an `Address` from this Public Key
127
+ ///
128
+ /// An `Address` can be derived from a `Secp256r1PublicKey` by hashing the bytes of the public
129
+ /// key prefixed with the Secp256r1 `SignatureScheme` flag (`0x02`).
130
+ ///
131
+ /// `hash( 0x02 || 33-byte secp256r1 public key)`
132
+ ///
133
+ /// ```
134
+ /// use sui_sdk_types::hash::Hasher;
135
+ /// use sui_sdk_types::Address;
136
+ /// use sui_sdk_types::Secp256r1PublicKey;
137
+ ///
138
+ /// let public_key_bytes = [0; 33];
139
+ /// let mut hasher = Hasher::new();
140
+ /// hasher.update([0x02]); // The SignatureScheme flag for Secp256r1 is `2`
141
+ /// hasher.update(public_key_bytes);
142
+ /// let address = Address::new(hasher.finalize().into_inner());
143
+ /// println!("Address: {}", address);
144
+ ///
145
+ /// let public_key = Secp256r1PublicKey::new(public_key_bytes);
146
+ /// assert_eq!(address, public_key.derive_address());
147
+ /// ```
76
148
pub fn derive_address ( & self ) -> Address {
77
149
let mut hasher = Hasher :: new ( ) ;
78
150
self . write_into_hasher ( & mut hasher) ;
@@ -87,7 +159,11 @@ impl crate::Secp256r1PublicKey {
87
159
}
88
160
89
161
impl crate :: ZkLoginPublicIdentifier {
90
- /// Define as iss_bytes_len || iss_bytes || padded_32_byte_address_seed.
162
+ /// Derive an `Address` from this `ZkLoginPublicIdentifier` by hashing the byte length of the
163
+ /// `iss` followed by the `iss` bytes themselves and the full 32 byte `address_seed` value, all
164
+ /// prefixed with the zklogin `SignatureScheme` flag (`0x05`).
165
+ ///
166
+ /// `hash( 0x05 || iss_bytes_len || iss_bytes || 32_byte_address_seed )`
91
167
pub fn derive_address_padded ( & self ) -> Address {
92
168
let mut hasher = Hasher :: new ( ) ;
93
169
self . write_into_hasher_padded ( & mut hasher) ;
@@ -102,7 +178,11 @@ impl crate::ZkLoginPublicIdentifier {
102
178
hasher. update ( self . address_seed ( ) . padded ( ) ) ;
103
179
}
104
180
105
- /// Define as iss_bytes_len || iss_bytes || unpadded_32_byte_address_seed.
181
+ /// Derive an `Address` from this `ZkLoginPublicIdentifier` by hashing the byte length of the
182
+ /// `iss` followed by the `iss` bytes themselves and the `address_seed` bytes with any leading
183
+ /// zero-bytes stripped, all prefixed with the zklogin `SignatureScheme` flag (`0x05`).
184
+ ///
185
+ /// `hash( 0x05 || iss_bytes_len || iss_bytes || unpadded_32_byte_address_seed )`
106
186
pub fn derive_address_unpadded ( & self ) -> Address {
107
187
let mut hasher = Hasher :: new ( ) ;
108
188
hasher. update ( [ self . scheme ( ) . to_u8 ( ) ] ) ;
@@ -134,6 +214,13 @@ impl crate::ZkLoginPublicIdentifier {
134
214
}
135
215
136
216
impl crate :: PasskeyPublicKey {
217
+ /// Derive an `Address` from this Passkey Public Key
218
+ ///
219
+ /// An `Address` can be derived from a `PasskeyPublicKey` by hashing the bytes of the
220
+ /// `Secp256r1PublicKey` that corresponds to this passkey prefixed with the Passkey
221
+ /// `SignatureScheme` flag (`0x06`).
222
+ ///
223
+ /// `hash( 0x06 || 33-byte secp256r1 public key)`
137
224
pub fn derive_address ( & self ) -> Address {
138
225
let mut hasher = Hasher :: new ( ) ;
139
226
self . write_into_hasher ( & mut hasher) ;
@@ -148,14 +235,23 @@ impl crate::PasskeyPublicKey {
148
235
}
149
236
150
237
impl crate :: MultisigCommittee {
151
- /// Derive an Address from a MultisigCommittee. A MultiSig address
152
- /// is defined as the 32-byte Blake2b hash of serializing the flag, the
153
- /// threshold, concatenation of all n flag, public keys and
154
- /// its weight. `flag_MultiSig || threshold || flag_1 || pk_1 || weight_1
155
- /// || ... || flag_n || pk_n || weight_n`.
238
+ /// Derive an `Address` from this MultisigCommittee.
239
+ ///
240
+ /// A MultiSig address
241
+ /// is defined as the 32-byte Blake2b hash of serializing the `SignatureScheme` flag (0x03), the
242
+ /// threshold (in little endian), and the concatenation of all n flag, public keys and
243
+ /// its weight.
244
+ ///
245
+ /// `hash(0x03 || threshold || flag_1 || pk_1 || weight_1
246
+ /// || ... || flag_n || pk_n || weight_n)`.
247
+ ///
248
+ /// When flag_i is ZkLogin, the pk_i for the [`ZkLoginPublicIdentifier`] refers to the same
249
+ /// input used when deriving the address using the
250
+ /// [`ZkLoginPublicIdentifier::derive_address_padded`] method (using the full 32-byte
251
+ /// `address_seed` value).
156
252
///
157
- /// When flag_i is ZkLogin, pk_i refers to [struct ZkLoginPublicIdentifier]
158
- /// derived from padded address seed in bytes and iss.
253
+ /// [` ZkLoginPublicIdentifier`]: crate::ZkLoginPublicIdentifier
254
+ /// [`ZkLoginPublicIdentifier::derive_address_padded`]: crate::ZkLoginPublicIdentifier::derive_address_padded
159
255
pub fn derive_address ( & self ) -> Address {
160
256
use crate :: MultisigMemberPublicKey :: * ;
161
257
@@ -198,6 +294,9 @@ mod type_digest {
198
294
use crate :: TransactionEventsDigest ;
199
295
200
296
impl Object {
297
+ /// Calculate the digest of this `Object`
298
+ ///
299
+ /// This is done by hashing the BCS bytes of this `Object` prefixed
201
300
pub fn digest ( & self ) -> ObjectDigest {
202
301
const SALT : & str = "Object::" ;
203
302
let digest = type_digest ( SALT , self ) ;
@@ -298,9 +397,9 @@ mod signing_message {
298
397
}
299
398
}
300
399
301
- /// A 1-byte domain separator for hashing Object ID in Sui. It is starting from 0xf0
302
- /// to ensure no hashing collision for any ObjectId vs Address which is derived
303
- /// as the hash of `flag || pubkey`.
400
+ /// A 1-byte domain separator for deriving `ObjectId`s in Sui. It is starting from ` 0xf0` to ensure
401
+ /// no hashing collision for any ObjectId vs Address which is derived as the hash of `flag ||
402
+ /// pubkey`.
304
403
#[ derive( Copy , Clone , PartialEq , Eq , Debug , Hash ) ]
305
404
#[ cfg_attr( feature = "proptest" , derive( test_strategy:: Arbitrary ) ) ]
306
405
#[ repr( u8 ) ]
0 commit comments